1 /* 2 * Copyright 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.build.lint 18 19 import androidx.build.lint.RestrictToDetector.Companion.sameLibraryGroupPrefix 20 import com.android.tools.lint.checks.infrastructure.ProjectDescription 21 import com.android.tools.lint.checks.infrastructure.TestFile 22 import com.android.tools.lint.checks.infrastructure.TestFiles.mavenLibrary 23 import com.android.tools.lint.checks.infrastructure.TestMode 24 import com.android.tools.lint.detector.api.Project 25 import com.android.tools.lint.model.DefaultLintModelJavaLibrary 26 import com.android.tools.lint.model.DefaultLintModelMavenName 27 import com.android.tools.lint.model.DefaultLintModelModuleLibrary 28 import java.io.File 29 30 class RestrictToDetectorTest : 31 AbstractLintDetectorTest( 32 useDetector = RestrictToDetector(), 33 useIssues = listOf(RestrictToDetector.RESTRICTED), 34 ) { 35 testRestrictToSubClassnull36 fun testRestrictToSubClass() { 37 val expected = 38 """ 39 src/test/pkg/RestrictToSubclassTest.java:26: Error: Class1.onSomething can only be called from subclasses [RestrictedApiAndroidX] 40 cls.onSomething(); // ERROR: Not from subclass 41 ~~~~~~~~~~~ 42 src/test/pkg/RestrictToSubclassTest.java:27: Error: Class1.counter can only be accessed from subclasses [RestrictedApiAndroidX] 43 int counter = cls.counter; // ERROR: Not from subclass 44 ~~~~~~~ 45 2 errors, 0 warnings 46 """ 47 48 lint() 49 .files( 50 java( 51 """ 52 package test.pkg; 53 54 import androidx.annotation.RestrictTo; 55 56 @SuppressWarnings("ClassNameDiffersFromFileName") 57 public class RestrictToSubclassTest { 58 public static class Class1 { 59 @RestrictTo(RestrictTo.Scope.SUBCLASSES) 60 public void onSomething() { 61 } 62 63 @RestrictTo(RestrictTo.Scope.SUBCLASSES) 64 public int counter; 65 } 66 67 public static class SubClass extends Class1 { 68 public void test1() { 69 onSomething(); // OK: Call from subclass 70 int counter = cls.counter; // OK: Reference from subclass 71 } 72 } 73 74 @SuppressWarnings("MethodMayBeStatic") 75 public static class NotSubClass { 76 public void test2(Class1 cls) { 77 cls.onSomething(); // ERROR: Not from subclass 78 int counter = cls.counter; // ERROR: Not from subclass 79 } 80 } 81 } 82 """ 83 ) 84 .indented(), 85 SUPPORT_ANNOTATIONS_JAR 86 ) 87 .run() 88 .expect(expected) 89 } 90 testRestrictToGroupIdnull91 fun testRestrictToGroupId() { 92 val project = 93 project() 94 .files( 95 java( 96 """ 97 package test.pkg; 98 import library.pkg.internal.InternalClass; 99 import library.pkg.Library; 100 import library.pkg.PrivateClass; 101 102 @SuppressWarnings("ClassNameDiffersFromFileName") 103 public class TestLibrary { 104 public void test() { 105 Library.method(); // OK 106 Library.privateMethod(); // ERROR 107 PrivateClass.method(); // ERROR 108 InternalClass.method(); // ERROR 109 } 110 111 @Override 112 public method() { 113 super.method(); // ERROR 114 } 115 } 116 """ 117 ) 118 .indented(), 119 java( 120 "src/test/java/test/pkg/UnitTestLibrary.java", 121 """ 122 package test.pkg; 123 import library.pkg.PrivateClass; 124 125 @SuppressWarnings("ClassNameDiffersFromFileName") 126 public class UnitTestLibrary { 127 public void test() { 128 PrivateClass.method(); // Not enforced in tests 129 } 130 } 131 """ 132 ) 133 .indented(), 134 library, 135 gradle( 136 """ 137 apply plugin: 'com.android.application' 138 139 dependencies { 140 compile 'my.group.id:mylib:25.0.0-SNAPSHOT' 141 } 142 """ 143 ) 144 .indented(), 145 SUPPORT_ANNOTATIONS_JAR 146 ) 147 lint() 148 .projects(project) 149 .testModes(TestMode.DEFAULT) 150 .run() 151 .expect( 152 """ 153 src/main/java/test/pkg/TestLibrary.java:10: Error: Library.privateMethod can only be called from within the same library group (referenced groupId=my.group.id from groupId=<unknown>) [RestrictedApiAndroidX] 154 Library.privateMethod(); // ERROR 155 ~~~~~~~~~~~~~ 156 src/main/java/test/pkg/TestLibrary.java:11: Error: PrivateClass.method can only be called from within the same library group (referenced groupId=my.group.id from groupId=<unknown>) [RestrictedApiAndroidX] 157 PrivateClass.method(); // ERROR 158 ~~~~~~ 159 src/main/java/test/pkg/TestLibrary.java:12: Error: InternalClass.method can only be called from within the same library group (referenced groupId=my.group.id from groupId=<unknown>) [RestrictedApiAndroidX] 160 InternalClass.method(); // ERROR 161 ~~~~~~ 162 3 errors, 0 warnings 163 """ 164 ) 165 } 166 testRestrictToLibrarynull167 fun testRestrictToLibrary() { 168 // 120087311: Enforce RestrictTo(LIBRARY) when the API is defined in another project 169 val library = 170 project() 171 .files( 172 java( 173 """ 174 package com.example.mylibrary; 175 176 import androidx.annotation.RestrictTo; 177 178 public class LibraryCode { 179 // No restriction: any access is fine. 180 public static int FIELD1; 181 182 // Scoped to same library: accessing from 183 // lib is okay, from app is not. 184 @RestrictTo(RestrictTo.Scope.LIBRARY) 185 public static int FIELD2; 186 187 // Scoped to same library group: whether accessing 188 // from app is okay depends on whether they are in 189 // the same library group (=groupId). In this test 190 // project we don't know what they are so there's 191 // no warning generated. 192 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 193 public static int FIELD3; 194 195 public static void method1() { 196 } 197 198 @RestrictTo(RestrictTo.Scope.LIBRARY) 199 public static void method2() { 200 } 201 202 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 203 public static void method3() { 204 } 205 } 206 """ 207 ) 208 .indented(), 209 java( 210 """ 211 package test.pkg; 212 213 import com.example.mylibrary.LibraryCode; 214 215 // Access within the same library -- all OK 216 public class LibraryCode2 { 217 public void method() { 218 LibraryCode.method1(); // OK 219 LibraryCode.method2(); // OK 220 LibraryCode.method3(); // OK 221 int f1 = LibraryCode.FIELD1; // OK 222 int f2 = LibraryCode.FIELD2; // OK 223 int f3 = LibraryCode.FIELD3; // OK 224 } 225 } 226 """ 227 ) 228 .indented(), 229 SUPPORT_ANNOTATIONS_JAR 230 ) 231 .name("lib") 232 .type(ProjectDescription.Type.LIBRARY) 233 234 val app = 235 project() 236 .files( 237 kotlin( 238 """ 239 package com.example.myapplication 240 241 import com.example.mylibrary.LibraryCode 242 243 fun test() { 244 LibraryCode.method1() 245 LibraryCode.method2() 246 LibraryCode.method3() 247 val f1 = LibraryCode.FIELD1 248 val f2 = LibraryCode.FIELD2 249 val f3 = LibraryCode.FIELD3 250 } 251 """ 252 ) 253 .indented(), 254 SUPPORT_ANNOTATIONS_JAR 255 ) 256 .dependsOn(library) 257 .name("app") 258 259 lint() 260 .projects(library, app) 261 .run() 262 .expect( 263 """ 264 src/com/example/myapplication/test.kt:7: Error: LibraryCode.method2 can only be called from within the same library (lib) [RestrictedApiAndroidX] 265 LibraryCode.method2() 266 ~~~~~~~ 267 src/com/example/myapplication/test.kt:10: Error: LibraryCode.FIELD2 can only be accessed from within the same library (lib) [RestrictedApiAndroidX] 268 val f2 = LibraryCode.FIELD2 269 ~~~~~~ 270 2 errors, 0 warnings 271 """ 272 ) 273 } 274 testHierarchynull275 fun testHierarchy() { 276 val project = 277 project() 278 .files( 279 java( 280 """ 281 package test.pkg; 282 import library.pkg.PrivateClass; 283 284 @SuppressWarnings("ClassNameDiffersFromFileName") 285 public class TestLibrary1 extends PrivateClass { 286 @Override 287 public void method() { 288 super.method(); // ERROR 289 } 290 } 291 """ 292 ) 293 .indented(), 294 java( 295 """ 296 package test.pkg; 297 import library.pkg.PrivateClass; 298 299 @SuppressWarnings("ClassNameDiffersFromFileName") 300 public class TestLibrary2 extends PrivateClass { 301 } 302 """ 303 ) 304 .indented(), 305 java( 306 """ 307 package test.pkg; 308 309 @SuppressWarnings("ClassNameDiffersFromFileName") 310 public class Inheriting1 extends TestLibrary1 { 311 public void test() { 312 method(); // OK -- overridden without annotation 313 } 314 } 315 """ 316 ) 317 .indented(), 318 java( 319 """ 320 package test.pkg; 321 322 @SuppressWarnings("ClassNameDiffersFromFileName") 323 public class Inheriting2 extends TestLibrary2 { 324 public void test() { 325 method(); // ERROR - not overridden, pointing into library 326 } 327 } 328 """ 329 ) 330 .indented(), 331 library, 332 gradle( 333 """ 334 apply plugin: 'com.android.application' 335 336 dependencies { 337 compile 'my.group.id:mylib:25.0.0-SNAPSHOT' 338 } 339 """ 340 ) 341 .indented(), 342 SUPPORT_ANNOTATIONS_JAR 343 ) 344 lint() 345 .projects(project) 346 .run() 347 .expect( 348 """ 349 src/main/java/test/pkg/Inheriting2.java:6: Error: PrivateClass.method can only be called from within the same library group (referenced groupId=my.group.id from groupId=<unknown>) [RestrictedApiAndroidX] 350 method(); // ERROR - not overridden, pointing into library 351 ~~~~~~ 352 src/main/java/test/pkg/TestLibrary1.java:5: Error: PrivateClass can only be accessed from within the same library group (referenced groupId=my.group.id from groupId=<unknown>) [RestrictedApiAndroidX] 353 public class TestLibrary1 extends PrivateClass { 354 ~~~~~~~~~~~~ 355 src/main/java/test/pkg/TestLibrary1.java:8: Error: PrivateClass.method can only be called from within the same library group (referenced groupId=my.group.id from groupId=<unknown>) [RestrictedApiAndroidX] 356 super.method(); // ERROR 357 ~~~~~~ 358 src/main/java/test/pkg/TestLibrary2.java:5: Error: PrivateClass can only be accessed from within the same library group (referenced groupId=my.group.id from groupId=<unknown>) [RestrictedApiAndroidX] 359 public class TestLibrary2 extends PrivateClass { 360 ~~~~~~~~~~~~ 361 4 errors, 0 warnings 362 """ 363 ) 364 } 365 testRestrictedInheritedAnnotationnull366 fun testRestrictedInheritedAnnotation() { 367 // Regression test for http://b.android.com/230387 368 // Ensure that when we perform the @RestrictTo check, we don't incorrectly 369 // inherit annotations from the base classes of AppCompatActivity and treat 370 // those as @RestrictTo on the whole AppCompatActivity class itself. 371 lint() 372 .files( 373 /* 374 Compiled version of these two classes: 375 package test.pkg; 376 import androidx.annotation.RestrictTo; 377 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 378 public class RestrictedParent { 379 } 380 and 381 package test.pkg; 382 public class Parent extends RestrictedParent { 383 public void myMethod() { 384 } 385 } 386 */ 387 base64gzip( 388 "libs/exploded-aar/my.group.id/mylib/25.0.0-SNAPSHOT/jars/classes.jar", 389 "" + 390 "H4sIAAAAAAAAAAvwZmYRYeDg4GB4VzvRkwEJcDKwMPi6hjjqevq56f87xcDA" + 391 "zBDgzc4BkmKCKgnAqVkEiOGafR39PN1cg0P0fN0++5457eOtq3eR11tX69yZ" + 392 "85uDDK4YP3hapOflq+Ppe7F0FQtnxAvJI9JSUi/Flj5boia2XCujYuk0C1HV" + 393 "tGei2iKvRV8+zf5U9LGIEeyWNZtvhngBbfJCcYspmlvkgbgktbhEvyA7XT8I" + 394 "yCjKTC5JTQlILErNK9FLzkksLp4aGOvN5Chi+/j6tMxZqal2rK7xV+y+RLio" + 395 "iRyatGmWgO2RHdY3blgp7978b/28JrlfjH9XvMh66Cxwg6fY/tze73Mknz3+" + 396 "/Fb2gOaqSJXAbRvyEpsVi/WmmojznPzbrOe8al3twYCCJULbP25QP8T3nrVl" + 397 "iszbjwtOO1uerD8wpXKSoPNVQyWjby925u8WablkfCj/Y4BG8bEJua8tvhzZ" + 398 "OsdnSr35HJ4fM4RbpbWV2xctPGY0ySUu2Es6b0mYyobnBU/bo36VifS7WZmY" + 399 "zZ+aPknWN+mlIX9S4kKnxNuXlSedMZ0ilGj7IFCl43WF3bq5L00Mn809NjW6" + 400 "+L18/p1nsdrtIpd4ptrLnwmYs+cE345Xt8/ec6g4dkjs8EX7EMmy56+OmQl9" + 401 "mT75aMblsyfSNDYvt5xgV8NavVCBsTsnjSttg4PZ97sNrikn1TeavD2l6L/P" + 402 "Y2uqVSu7QWPomoUuGdMmKJltLIr8yQSKpPpfEa8iGBkYfJjwRZIociQhR01q" + 403 "n7//IQeBo/cv1AesjsiX2cmp9u1B4OOjLcGmbpzfl949oFRytszwY3Kl0cMD" + 404 "7B+cJZetzex5l3hvj/nn0+euf8/jf8BVyMGuzviL0Y/zX6/WlL2qFs8XSx7c" + 405 "e3mnypfg0BPtb9P0zoacuT5nzlIr4dczDVZ9sl+YPX2VypGVU5f6xsWLnVxs" + 406 "sGnD9ZZ3z/7G3Vp6jvPh5nuzfPxCWmVMpadrf1RT2vHhx2Z7k8QLav53JKZG" + 407 "zjQ35rn48PPq64yhNuHzYw95rbn3Q/hLYD/zujpZqxdFvbNYvwhs+qSpWxNY" + 408 "/Yd9b7zC1oSQfFl5cErewhTw/BEwCIIYQYHEyCTCgJqvYDkOlClRAUoWRdeK" + 409 "nEFEULTZ4sigyCaA4gg59uRRTDhJOFuhG4bsS1EUw/KYcER/gDcrG0gBCxDy" + 410 "ArVNZgbxABAMMsu2BAAA" 411 ), 412 java( 413 "" + 414 "package test.pkg;\n" + 415 "\n" + 416 "public class Cls extends Parent {\n" + 417 " @Override\n" + 418 " public void myMethod() {\n" + 419 " super.myMethod();\n" + 420 " }\n" + 421 "}\n" 422 ), 423 gradle( 424 "" + 425 "apply plugin: 'com.android.application'\n" + 426 "\n" + 427 "dependencies {\n" + 428 " compile 'my.group.id:mylib:25.0.0-SNAPSHOT'\n" + 429 "}" 430 ), 431 SUPPORT_ANNOTATIONS_JAR 432 ) 433 .run() 434 .expectClean() 435 } 436 testRestrictedClassOrInterfaceUsagenull437 fun testRestrictedClassOrInterfaceUsage() { 438 lint() 439 .files( 440 kotlin( 441 """ 442 package test.pkg 443 444 class MyClass : RestrictedClass() 445 """ 446 ), 447 java( 448 """ 449 package test.pkg; 450 451 @SuppressWarnings("ClassNameDiffersFromFileName") 452 public class MyJavaClass extends RestrictedClass implements RestrictedInterface { 453 } 454 """ 455 ) 456 .indented(), 457 java( 458 "src/androidTest/java/test/pkg/MyTestJavaClass.java", 459 """ 460 package test.pkg; 461 462 @SuppressWarnings("ClassNameDiffersFromFileName") 463 public class MyTestJavaClass extends RestrictedClass { 464 } 465 """ 466 ) 467 .indented(), 468 kotlin( 469 """ 470 package test.pkg 471 472 import androidx.annotation.RestrictTo 473 474 @RestrictTo(RestrictTo.Scope.TESTS) 475 open class RestrictedClass 476 """ 477 ) 478 .indented(), 479 kotlin( 480 """ 481 package test.pkg 482 483 import androidx.annotation.RestrictTo 484 485 @RestrictTo(RestrictTo.Scope.TESTS) 486 interface RestrictedInterface 487 """ 488 ) 489 .indented(), 490 gradle( 491 """ 492 android { 493 lintOptions { 494 checkTestSources true 495 } 496 } 497 """ 498 ) 499 .indented(), 500 SUPPORT_ANNOTATIONS_JAR 501 ) 502 .skipTestModes(TestMode.TYPE_ALIAS) 503 .run() 504 .expect( 505 """ 506 src/main/kotlin/test/pkg/MyClass.kt:4: Error: RestrictedClass can only be called from tests [RestrictedApiAndroidX] 507 class MyClass : RestrictedClass() 508 ~~~~~~~~~~~~~~~ 509 src/main/java/test/pkg/MyJavaClass.java:4: Error: RestrictedClass can only be accessed from tests [RestrictedApiAndroidX] 510 public class MyJavaClass extends RestrictedClass implements RestrictedInterface { 511 ~~~~~~~~~~~~~~~ 512 src/main/java/test/pkg/MyJavaClass.java:4: Error: RestrictedInterface can only be accessed from tests [RestrictedApiAndroidX] 513 public class MyJavaClass extends RestrictedClass implements RestrictedInterface { 514 ~~~~~~~~~~~~~~~~~~~ 515 3 errors, 0 warnings 516 """ 517 ) 518 } 519 test123545341null520 fun test123545341() { 521 // Regression test for 522 // 123545341: RestrictTo(TESTS) doesn't allow same class to use methods 523 // (Note that that test asks for the following not to be an error, but this is 524 // deliberate and we're testing the enforcement here) 525 lint() 526 .files( 527 java( 528 """ 529 package test.pkg; 530 531 import androidx.annotation.RestrictTo; 532 import static androidx.annotation.RestrictTo.Scope.TESTS; 533 534 class Outer { 535 private Inner innerInstance; 536 537 @RestrictTo(TESTS) 538 class Inner { 539 public void method() { 540 } 541 } 542 543 private void outerMethod() { 544 // This is marked as invalid 545 innerInstance.method(); 546 } 547 } 548 """ 549 ), 550 SUPPORT_ANNOTATIONS_JAR 551 ) 552 .run() 553 .expect( 554 """ 555 src/test/pkg/Outer.java:8: Error: Inner can only be accessed from tests [RestrictedApiAndroidX] 556 private Inner innerInstance; 557 ~~~~~ 558 src/test/pkg/Outer.java:18: Error: Inner.method can only be called from tests [RestrictedApiAndroidX] 559 innerInstance.method(); 560 ~~~~~~ 561 2 errors, 0 warnings 562 """ 563 ) 564 } 565 test169255669null566 fun test169255669() { 567 // Regression test for 169255669: ClassCastException in RestrictToDetector. 568 @Suppress("ConvertSecondaryConstructorToPrimary") 569 lint() 570 .files( 571 kotlin( 572 """ 573 package test.pkg 574 575 import androidx.annotation.RestrictTo 576 577 class Foo { 578 @RestrictTo(RestrictTo.Scope.SUBCLASSES) 579 constructor() 580 } 581 582 @RestrictTo(RestrictTo.Scope.SUBCLASSES) 583 val foo = Foo() 584 """ 585 ) 586 .indented(), 587 SUPPORT_ANNOTATIONS_JAR 588 ) 589 .run() 590 .expect( 591 """ 592 src/test/pkg/Foo.kt:11: Error: Foo can only be called from subclasses [RestrictedApiAndroidX] 593 val foo = Foo() 594 ~~~ 595 1 errors, 0 warnings 596 """ 597 ) 598 } 599 test169610406null600 fun test169610406() { 601 // 169610406: Strange warning from RestrictToDetector for Kotlin property 602 // initialized by constructor call 603 lint() 604 .files( 605 kotlin( 606 """ 607 package test.pkg 608 609 import androidx.annotation.RestrictTo 610 import androidx.annotation.RestrictTo.Scope.SUBCLASSES 611 612 class Foo 613 open class Bar { 614 // No use site target specified; Kotlin will take this to refer to the 615 // field only; lint will also interpret this as applying to getters and setters 616 @RestrictTo(SUBCLASSES) 617 val foo1: Foo = Foo() 618 619 // Field explicitly requested; lint only enforce this on field references, not getters/setters 620 @field:RestrictTo(SUBCLASSES) 621 val foo2: Foo = Foo() 622 623 // Setter only; don't enforce on getter 624 @set:RestrictTo(SUBCLASSES) 625 var foo3: Foo? = Foo() 626 627 // Getter only, don't enforce on setter 628 @get:RestrictTo(SUBCLASSES) 629 var foo4: Foo? = Foo() 630 } 631 """ 632 ) 633 .indented(), 634 kotlin( 635 """ 636 package test.pkg 637 class Sub : Bar() { 638 fun test() { 639 val test = foo1 // OK 1 640 println(foo1) // OK 2 641 println(foo2) // OK 3 642 println(foo3) // OK 4 643 println(foo5) // OK 5 644 } 645 } 646 class NotSub(private val bar: Bar) { 647 fun test() { 648 val test = bar.foo1 // WARN 1 649 println(bar.foo1) // WARN 2 650 val test2 = bar.foo2 // OK 6 651 println(bar.foo2) // OK 7 652 val test3 = bar.foo3 // OK 8 653 println(bar.foo3) // OK 9 654 bar.foo3 = null // WARN 3 655 println(bar.foo4) // WARN 4 656 bar.foo4 = null // OK 10 657 } 658 } 659 """ 660 ) 661 .indented(), 662 SUPPORT_ANNOTATIONS_JAR 663 ) 664 .run() 665 .expect( 666 """ 667 src/test/pkg/Sub.kt:13: Error: Bar.getFoo1 can only be called from subclasses [RestrictedApiAndroidX] 668 val test = bar.foo1 // WARN 1 669 ~~~~ 670 src/test/pkg/Sub.kt:14: Error: Bar.getFoo1 can only be called from subclasses [RestrictedApiAndroidX] 671 println(bar.foo1) // WARN 2 672 ~~~~ 673 src/test/pkg/Sub.kt:19: Error: Bar.setFoo3 can only be called from subclasses [RestrictedApiAndroidX] 674 bar.foo3 = null // WARN 3 675 ~~~~ 676 src/test/pkg/Sub.kt:20: Error: Bar.getFoo4 can only be called from subclasses [RestrictedApiAndroidX] 677 println(bar.foo4) // WARN 4 678 ~~~~ 679 4 errors, 0 warnings 680 """ 681 ) 682 } 683 testGetMavenCoordinateFromIdentifiernull684 fun testGetMavenCoordinateFromIdentifier() { 685 assertEquals( 686 "androidx.wear.tiles:tiles-material:", 687 DefaultLintModelModuleLibrary(":@@:wear:tiles:tiles-material", "", null, false) 688 .getMavenNameFromIdentifier()!! 689 .toString() 690 ) 691 692 assertEquals( 693 "androidx.wear.tiles:tiles-material:", 694 DefaultLintModelModuleLibrary(":@@:wear:tiles:tiles-material::debug", "", null, false) 695 .getMavenNameFromIdentifier()!! 696 .toString() 697 ) 698 699 assertEquals( 700 null, 701 DefaultLintModelModuleLibrary("", "", null, false).getMavenNameFromIdentifier() 702 ) 703 } 704 testFindMavenNameWithJarFileInPathnull705 fun testFindMavenNameWithJarFileInPath() { 706 val mavenName = DefaultLintModelMavenName("", "") 707 val path = "/media/nvme/android/androidx-main/out/androidx/health/connect/connect-client" 708 val filePath = 709 "$path/build/.transforms/7940653434057db25345237f4ed56def/transformed/out" + 710 "/jars/libs/repackaged.jar" 711 val library = 712 DefaultLintModelJavaLibrary("", listOf(File(filePath)), mavenName, false, null) 713 714 assertEquals(mavenName, listOf(library).findMavenNameWithJarFileInPath(path)) 715 } 716 testRestrictToLibraryViaGradleModelnull717 fun testRestrictToLibraryViaGradleModel() { 718 val library = 719 project() 720 .files( 721 java( 722 """ 723 package com.example.mylibrary; 724 725 import androidx.annotation.RestrictTo; 726 727 public class LibraryCode { 728 // No restriction: any access is fine. 729 public static int FIELD1; 730 731 // Scoped to same library: accessing from 732 // lib is okay, from app is not. 733 @RestrictTo(RestrictTo.Scope.LIBRARY) 734 public static int FIELD2; 735 736 // Scoped to same library group: whether accessing 737 // from app is okay depends on whether they are in 738 // the same library group (=groupId). In this test 739 // project we don't know what they are so there's 740 // no warning generated. 741 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 742 public static int FIELD3; 743 744 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) 745 public static int FIELD4; 746 747 public static void method1() { 748 } 749 750 @RestrictTo(RestrictTo.Scope.LIBRARY) 751 public static void method2() { 752 } 753 754 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 755 public static void method3() { 756 } 757 758 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) 759 public static void method4() { 760 } 761 } 762 """ 763 ) 764 .indented(), 765 java( 766 """ 767 package test.pkg; 768 769 import com.example.mylibrary.LibraryCode; 770 771 // Access within the same library -- all OK 772 public class LibraryCode2 { 773 public void method() { 774 LibraryCode.method1(); // OK 775 LibraryCode.method2(); // OK 776 LibraryCode.method3(); // OK 777 LibraryCode.method4(); // OK 778 int f1 = LibraryCode.FIELD1; // OK 779 int f2 = LibraryCode.FIELD2; // OK 780 int f3 = LibraryCode.FIELD3; // OK 781 int f4 = LibraryCode.FIELD4; // OK 782 } 783 } 784 """ 785 ) 786 .indented(), 787 gradle( 788 """ 789 apply plugin: 'com.android.library' 790 group=test.pkg.library 791 """ 792 ) 793 .indented(), 794 SUPPORT_ANNOTATIONS_JAR 795 ) 796 .name("lib1") 797 798 // Add library3 to test case when group doesn't contain any dots. 799 val library3 = 800 project() 801 .files( 802 java( 803 """ 804 package com.example.dotless; 805 806 import androidx.annotation.RestrictTo; 807 808 public class DotlessCode { 809 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) 810 public static void method() { 811 } 812 } 813 """ 814 ) 815 .indented(), 816 gradle( 817 """ 818 apply plugin: 'com.android.library' 819 group=dotless 820 """ 821 ) 822 .indented(), 823 SUPPORT_ANNOTATIONS_JAR 824 ) 825 .name("lib3") 826 827 val library2 = 828 project() 829 .files( 830 kotlin( 831 """ 832 package com.example.myapplication 833 834 import com.example.mylibrary.LibraryCode 835 import com.example.dotless.DotlessCode 836 837 fun test() { 838 LibraryCode.method1() // OK 839 LibraryCode.method2() // ERROR 840 LibraryCode.method3() // ERROR 841 LibraryCode.method4() // ERROR 842 val f1 = LibraryCode.FIELD1 // OK 843 val f2 = LibraryCode.FIELD2 // ERROR 844 val f3 = LibraryCode.FIELD3 // ERROR 845 val f4 = LibraryCode.FIELD4 // ERROR 846 DotlessCode.method() // ERROR 847 } 848 """ 849 ) 850 .indented(), 851 gradle( 852 """ 853 apply plugin: 'com.android.library' 854 group=other.app 855 """ 856 ) 857 .indented() 858 ) 859 .name("lib2") 860 .dependsOn(library) 861 .dependsOn(library3) 862 863 // Make sure projects are placed correctly on disk: to do this, record 864 // project locations with a special client, then after the lint run make 865 // sure the locations are correct. 866 library2.under(library) 867 library3.under(library) 868 var libDir1: File? = null 869 var libDir2: File? = null 870 var libDir3: File? = null 871 val factory: () -> com.android.tools.lint.checks.infrastructure.TestLintClient = { 872 object : com.android.tools.lint.checks.infrastructure.TestLintClient() { 873 override fun registerProject(dir: File, project: Project) { 874 if (project.name == "lib1") { 875 libDir1 = dir 876 } else if (project.name == "lib2") { 877 libDir2 = dir 878 } else if (project.name == "lib3") { 879 libDir3 = dir 880 } 881 super.registerProject(dir, project) 882 } 883 } 884 } 885 assertEquals("LIBRARY:lib1", library.toString()) 886 887 lint() 888 .projects(library, library2, library3) 889 .reportFrom(library2) 890 .clientFactory(factory) 891 .run() 892 .expect( 893 """ 894 src/main/kotlin/com/example/myapplication/test.kt:8: Error: LibraryCode.method2 can only be called from within the same library (test.pkg.library:test_project-lib1) [RestrictedApiAndroidX] 895 LibraryCode.method2() // ERROR 896 ~~~~~~~ 897 src/main/kotlin/com/example/myapplication/test.kt:9: Error: LibraryCode.method3 can only be called from within the same library group (referenced groupId=test.pkg.library from groupId=other.app) [RestrictedApiAndroidX] 898 LibraryCode.method3() // ERROR 899 ~~~~~~~ 900 src/main/kotlin/com/example/myapplication/test.kt:10: Error: LibraryCode.method4 can only be called from within the same library group prefix (referenced groupId=test.pkg.library with prefix test.pkg from groupId=other.app) [RestrictedApiAndroidX] 901 LibraryCode.method4() // ERROR 902 ~~~~~~~ 903 src/main/kotlin/com/example/myapplication/test.kt:12: Error: LibraryCode.FIELD2 can only be accessed from within the same library (test.pkg.library:test_project-lib1) [RestrictedApiAndroidX] 904 val f2 = LibraryCode.FIELD2 // ERROR 905 ~~~~~~ 906 src/main/kotlin/com/example/myapplication/test.kt:13: Error: LibraryCode.FIELD3 can only be accessed from within the same library group (referenced groupId=test.pkg.library from groupId=other.app) [RestrictedApiAndroidX] 907 val f3 = LibraryCode.FIELD3 // ERROR 908 ~~~~~~ 909 src/main/kotlin/com/example/myapplication/test.kt:14: Error: LibraryCode.FIELD4 can only be accessed from within the same library group prefix (referenced groupId=test.pkg.library with prefix test.pkg from groupId=other.app) [RestrictedApiAndroidX] 910 val f4 = LibraryCode.FIELD4 // ERROR 911 ~~~~~~ 912 src/main/kotlin/com/example/myapplication/test.kt:15: Error: DotlessCode.method can only be called from within the same library group prefix (referenced groupId=dotless with prefix "" from groupId=other.app) [RestrictedApiAndroidX] 913 DotlessCode.method() // ERROR 914 ~~~~~~ 915 7 errors, 0 warnings 916 """ 917 ) 918 919 // Make sure project directories are laid out correctly 920 assertTrue(libDir2!!.parentFile.path == libDir1!!.path) 921 assertTrue(libDir3!!.parentFile.path == libDir1!!.path) 922 } 923 testLibraryGroupPrefixMatchesnull924 fun testLibraryGroupPrefixMatches() { 925 assertTrue(sameLibraryGroupPrefix("foo", "foo")) 926 assertFalse(sameLibraryGroupPrefix("foo", "bar")) 927 assertTrue(sameLibraryGroupPrefix("foo.bar", "foo.bar")) 928 assertFalse(sameLibraryGroupPrefix("foo.bar", "bar")) 929 assertFalse(sameLibraryGroupPrefix("foo.bar", "foo")) 930 931 assertTrue(sameLibraryGroupPrefix("foo.bar", "foo.baz")) 932 assertTrue(sameLibraryGroupPrefix("com.foo.bar", "com.foo.baz")) 933 assertFalse(sameLibraryGroupPrefix("com.foo.bar", "com.bar.qux")) 934 935 // Implementation for AndroidX differs from the standard RestrictToDetector, since we 936 // treat LIBRARY_GROUP_PREFIX as anything in the androidx.* package. See b/297047524. 937 assertTrue(sameLibraryGroupPrefix("androidx.foo.foo", "androidx.bar.bar")) 938 } 939 test278573413null940 fun test278573413() { 941 // Regression test for b/278573413. 942 lint() 943 .files( 944 kotlin( 945 """ 946 package test.pkg 947 948 import library.pkg.PrivateKotlinClass 949 950 class Test : PrivateKotlinClass { 951 override fun method() {} 952 } 953 """ 954 ) 955 .indented(), 956 mavenLibrary( 957 "my.group.id:myklib:25.0.0-SNAPSHOT", 958 stubSources = 959 listOf( 960 kotlin( 961 """ 962 package library.pkg 963 964 import androidx.annotation.RestrictTo 965 966 @RestrictTo(RestrictTo.Scope.GROUP_ID) 967 open class PrivateKotlinClass { 968 open fun method() {} 969 } 970 """ 971 ) 972 .indented(), 973 ), 974 compileOnly = listOf(SUPPORT_ANNOTATIONS_JAR) 975 ), 976 gradle( 977 """ 978 apply plugin: 'com.android.application' 979 980 dependencies { 981 compile 'my.group.id:myklib:25.0.0-SNAPSHOT' 982 } 983 """ 984 ) 985 .indented(), 986 SUPPORT_ANNOTATIONS_JAR 987 ) 988 .allowKotlinClassStubs(true) 989 .run() 990 .expect( 991 """ 992 src/main/kotlin/test/pkg/Test.kt:5: Error: PrivateKotlinClass can only be accessed from within the same library group (referenced groupId=my.group.id from groupId=<unknown>) [RestrictedApiAndroidX] 993 class Test : PrivateKotlinClass { 994 ~~~~~~~~~~~~~~~~~~ 995 src/main/kotlin/test/pkg/Test.kt:6: Error: PrivateKotlinClass.method can only be called from within the same library group (referenced groupId=my.group.id from groupId=<unknown>) [RestrictedApiAndroidX] 996 override fun method() {} 997 ~~~~~~ 998 2 errors, 0 warnings 999 """ 1000 ) 1001 } 1002 1003 companion object { 1004 // Snapshot of support library: support-annotations-26.0.0-SNAPSHOT.jar 1005 // Note: avoiding string concatenation here due to b/180148524. 1006 // This is the toBase64gzip'ed version of 1007 // https://dl.google.com/android/maven2/androidx/annotation/annotation/1.3.0-alpha01/annotation-1.3.0-alpha01.jar 1008 private val SUPPORT_ANNOTATIONS_JAR_BASE64_GZIP: String = 1009 ("H4sIAAAAAAAAALS8dVQUXNvGi3R3p3R3d3cNIdI95ABDCxLS0o20tCCdgoQgSHdLSDcijUidwSf1fX2e" + 1010 "91vnHNbaa80fg6z12/e+9h3XFqAMA4sMBYWICAUFJQl1/wMN9dsPEmSpympLsiqqybHDQAF++GKNP/QB" + 1011 "CeQTEWTh/v2LqpJqinKyWtpsqnInqoMDKsqsbGNoyqxMw4MjtZock9zLG6sb0D/9Yz//VTNHSxcnW8sn" + 1012 "//FX//5F3L9/0czR0cnNzM3WyfE/fqd5noCN/AEU1CJkUf7idyQdbR00ga5sFiAzV9eQOFV1aE7M0CWq" + 1013 "qsDnX905ur86L/eSi3i/rpJJ4I0LAR+Z9nNR0irPSLzoNTlZxjiUJ3rV/TxMFTTuWcQ94kZ3cnR5jr6M" + 1014 "/4o8RoT0qQBWMfoEiEjrMT0NIFGOnUq/ftOuHHY4b1C3NafaeEdRajx1kqlUqxa7EZ1sjb5/0Ocs41DY" + 1015 "NpO1Vzf9E5LhBjeWHt2sRUGdjmJ3VsZdThDP2FE3Xp20ICmy4TpB1KSLXEpTxrVPXByJU50XZWh/bMd2" + 1016 "7hJWMaolzSWWzELuPIpUzFSnn0HoiAXR2bovIWImM7dRkfe3bxedL6OReBpuviUKftBZ5vIM/kycAQ0N" + 1017 "1yYMfvVs9U0KwGp+tbjH48UJnhTe02LBCyTZ92K7auiZPJmkfg9+hDuil3JDAQG7AVm0/wDXzM3J5W+A" + 1018 "RdWhJSGAZZdh8Y5Kqzj8cJMAuvrlYJkE7rigUd3UjdQ42p7spnnq4xmW6we3DGtlIQDDVbqr4f1BbuHE" + 1019 "y2+3X2HBsSgYr8iHRTJRJnsUs+UmZziReArHmIGJPAVlrdr2tGCize5dPFX3ImtORQvs0jI1FTowiUAR" + 1020 "DnPtdvE7mVcvZC4jogovg9pVOXESgIGickz2eFsLrWcYQkrmZA6Gkvxxa9Xtj5w7ZApRagYX8bZuUhee" + 1021 "JA6RcGr7ntOrd2ZLONBI92GIr6PfBFCAy7BQm7meZPWDH1LAmCzrp3mlb19eHYQJG6yROT5Ft1aOYCHA" + 1022 "i6k2AipL5HR5YhwkAW6nkF+D5knPZg9c2+SK16DChn0l08DBoYkW9Kr09OI/ErYgnAskg9Cdh6yHvyTs" + 1023 "9d+iFzriq/to179Hb/r/FL1WOGOveR9DyOIDu3fhos+U1LETugt09LLSk9vdtwnFNaw2S5eClxTXQJLd" + 1024 "46dqy0wvw3u5OsipC+uVuBwXrhHICsJj+CtyyPpXAMtU70wLUrghZNe3goIXnuQPoXBq+6HKYdzESAAf" + 1025 "UvfFPlxFXzTGdCkjP5/n8iEfKKb/0imxbJi2wzU1MfOO4pZFJafaYeblIGMD9IsmHNCbWVxMhsPFAGE4" + 1026 "3Hf1wVzz+PKiDc2ZlZivi81GmtQZsM81PF2WC1bWD1F+RCtaGGlF8rsyUP8arbaNC9DM8i+67yUgdD9I" + 1027 "weEe7S0HQOgiIsRmp2uuPWC1fYyzZmtL31gAUv2IfWlP/j10KxAOR7tUz7P6Brkp0iq/xKpDzQi4O6+v" + 1028 "zn5AkmYeHqDKNUjDku7Rsr/Vj1NAcK3GRrXWKKkzHE007LeVy9ZswtfftOsDCzYMcuDY8eFmdIGT6DcC" + 1029 "k4pOQ1fy0sMVSN4/gS+plNFJ/3jjP6qY3WfpgHJdTdCD2roLzRZBZNtp9GgrKGrf2+dGDt5uAeGajZSz" + 1030 "7uaQcnMsf6TzecfKSOKzXMEjqhHMAKSzYKVIw6Iv/hkOBx9GF9VQXrkq8XR6bUDPU58TEdptfmlvI840" + 1031 "Kc8322+XMbLwVG1TtMmNFt1ra6fcz7fYaFea6V/B+JGtFzsG370wLEEW1a/YuriY/dfADQyEyO7Y72iZ" + 1032 "WOIt0SwpDUVSa1QU+sZ5lf8KXLqIXwduTAJLdPErC+ziPp5HGXE65SH6zAG1HNw67LZ5j72JE3noqvt3" + 1033 "u8pgK2B66iyAmw5nGTaeiQwGCdU8zTiN/dZSNSpVPQq25atRBvx3kmGKZfnRzNuwLjzYjb3shKVuave6" + 1034 "20KRSOLU8l13b7+ajeIVowIZLlfCFnJnLmBipoIk5eFHcIjON3yXUSC6q4wj+vTmamWkH5Z4PjRoJ5CK" + 1035 "GZwm3OkRq/ogAHqJrFFL4shAmaHWwXnSonngEjk3QnRfGKK7Umju9AhqxGro73661KxeVNn966Xm5uby" + 1036 "j5fav9D9p0vtT7qK9hP/L+AK/38LtxsC1+8PuO89on8JdzLzKpjKjOIXcPuQgeP3cNcgi+4XcKVsHS2B" + 1037 "Lv9VGmRzoP2eUSBgyJ22Y6GTik79gzSs/CQN0plCAi7g/eXgXCKgLPlEuUp4riv1IylB/yFFmpsmXaTQ" + 1038 "2iqAPtu2ItsGD+3jEhUUVu56y0ZSA6s4ZF6S5++6TJM+fICIw3p6rsFwcAGamUjQpA4V6+DXT+LbNMrA" + 1039 "lga4T7PRVKEnx9Bsx/fikLx1k/SbOLxeurpmI+Ssa1mmXF3J7wmKy+1/SS8mbbEaWkHpg7OLnLyepvLp" + 1040 "TYbDy6jcViJClS1c+9DIcTI+z31ODu3BpQBfPG3/+tC31b447lGLvJfwueH452VXgUxmFAg66OV15W5+" + 1041 "PxGOWsdCJPuX8JVycgL9a/gi/xW+PAUFdbBvZW7TEfyfifcL8MqJgMwT27izvIq402JH3nhCXQhggLGX" + 1042 "edqJpL1sJh5RNSsphyoN6JMNuFuw8QWuUKlFa6EI6tjzjiWQWGSB+9N5Ox3W04rwraZx34Vb9dDtSBHT" + 1043 "v8JA5f+owkKGtY6lOYuYpbn1TXy73S4Z5CspvNpJ2fnIo0OhzGocy/NFFkb96Vp0g7Ii4IiRVPRcGLXw" + 1044 "Qayg6PtUIbenZjLVdpNOJ9vAwTVyJ1nKzkKOieRH3281UFRuwx7kVgOuElZwy8+WVw+3x+U3I/i79Prb" + 1045 "P5CtQYuAt7xgNElgWIPC+yJGze78/PULanZe9h6TH9lmiCDwfoV8Kv+HW03aDATScgcDXf6gW612n5Dd" + 1046 "Sa7g4o0Nv8/BTzI2s5WFsgjoABOQlG44SqWwNK/PUh/a4Ys9wwBm1kNFKi9YetKd+J98sWxrExd7ILLM" + 1047 "9d4r2CMYRYrbGRh/lMinYnOWzKnYtL7qVzEdAeZlLJ9B8ZtgFuVdqJ322qivZX7/mYGjWsMDvzQLE8NQ" + 1048 "h23We5gCiX9qMLgVMwFJ04RZq39p0X/0sbVbAxrajQa7IuLMFFoJk9V+SHPpdFho55Mdjz5oXuPQnZMn" + 1049 "Dx37N0MmLjfZmw0Qclv5SdS3Mr2kXo37v8tnCwAkPn0GthO49t2zUdhX4E14QvONMz8cJzP0lKxLQHoP" + 1050 "4UdwgvZF27QQaN/+IZeVtgFa2EOi0h3k9ju6+N9z2ZU93HcSY10QdjLEjCzliKYsHIQxs7qsPU/Y2J5u" + 1051 "Osb2mtQeInzNj3KNBhiaV6elZVlvLrZc3Zxcwi3D00NklUeEFKeFBk1ajTTXeYp8eErTParGrMezumGF" + 1052 "NfdTPZ9L/07v+aVsoRwA87VfUveDJdvOYP0vyUFvOOnHW4c9MNV6Sty9O9SFxrQ692iRVsyl5W94hW4Y" + 1053 "FAhAZCMy5yIviWpxpLgk+5WBmhpON0FicnIIpaAc/v1vYiss/qZ5q3FZ4BeXNwEr+16JU8Io2l6EKgfy" + 1054 "vlJaH/VIdz720DWbPZ+tNeZPHxaMK7WqeD9XiB/eAycoe8nJhKXEoPwo/nVqe+J0SgEcKJ+pmnE2pstI" + 1055 "8pzwSkCCVfmlZJQQuv9PNcNU48MmMwhjZ0glx/pPnF21LO0VHd0k3VSAZq5/8Nbouw9V3yG+RqfGZewX" + 1056 "hCGRpCLeVCzxsEFmzwnUh1TCo6Ux0nYojyEaCyWuVC7IYEdXnXjw2vts91Hht883G3jttOesuKz7+rM4" + 1057 "CgPVq2+0HZHKHtWfR/P0z7h7x8Vbj1P4wB7HfElIocZmSOr/nJvZG0F/lmOeIbHTkQwFu9nNZRqRK/Fw" + 1058 "q09jKRn6pIECDp03uadeuF7eJVtq3tfOVovXISG36fkH2IhFBRLePGG8123ytZJSAWsUaBueeZoXWTYy" + 1059 "c3EDN7EJgkbk8j3kWjU4O7IiHz6KTxosaQ3zsBXXlzawguMg+V/HM9QTtYQTtNjVI+8JTk5Gz4ltI8/d" + 1060 "sjkQ7xxopNADxqRpRNweG5+mSijxy2nYOodb6qxzQz13B0XCasYmxoglLFevS9Iaw2LgBwlyVxOJ517w" + 1061 "+Ldc+P4Pyhq6HJEHdM2e9veXgmZSa9RmJR5kVD+NxTVDmT+qPUH6ca923DcB5P+Sxkk7gZxcIPv0P6dx" + 1062 "90pttfPnNTgpc1QVrvpt2PKTtdCQj09bK0zjB9tn+VA9D9QIX1NnFIbvM7IS2ZGVOszxV9Rj2neA8a27" + 1063 "Swozi5PT7fqiq9UEgEMRK0LHKgYo3E6RJvmL9YoNSd19H8k6H4nhKMvDAoOTpqWsed5eYgjV6dOSLI2G" + 1064 "f7XpAscvceDvGAqtOh7fAJTvWo82ZbG1iY5TxUPXOKwYtHwI3Yh2x3I687eQYq+uxZBtLSsp5CwzUbiV" + 1065 "y9Nbb30PrYGo0Z/bO9wocZiMNm/NmnvoYKQDDtCvGXO+ltMmMTYUEwMWaN9RaXwgP/f9Fpwng+bOjmBM" + 1066 "bPwfiUaco4vbQwjZ1X+S6nu6Kk6O1v+JF1LeHUpcC4CDg+TV92og5Z0y/vpqR1IhJW3h3/M48vZOOr4d" + 1067 "4cS2kUGek7ObI6RldAJyNdFMLwHr4liV7MI89mRTG1i5NBYu7096h7zWjSouDhuaKutKasmH9XwpBran" + 1068 "ESt0LiqPnUW/HJePfU7jMUF2+LCfvfI2VTGYNpBLism+wiV98RaBjJh2Ag1PW/7IFTsYtXw1gnNk8z32" + 1069 "E4P9MKXGu2h+p8CcuVH161dgUrrJtFWLhXxRGedl+UoccaKvGFjRr08RzGTkIvf0rNb3b5w6P48TpjeH" + 1070 "H7lRag6AH30NX6SbR0WlffsU/Cr4uFIHUDib+zh2VeySN0AIHbw9TpAEFzMKdtkv2Flf/0nSraxgdv+n" + 1071 "8P2/VSGKtkPjtMczIl9hrjW6p38PX7fNtGFLMbGlTw8WVnnaNZ6tQdGjTsX3jQd7a2JJl1skKVro1+Ob" + 1072 "sxIOr6oYNBWEG/aVUFXUV79Xyn+MOhNvPae07WVwTTdnlGipPJ5i5Yn6+FJFZRpr2FXBllV7U/8+T5br" + 1073 "s1xDEcKiiCZkO0bppspKdF9Q9RPTXu8hcTLuldzoAV9zbHNph4psHmB1V0hDIpZNJxaejFxU/cnC1oVG" + 1074 "L5jtlIXX5fy++ZPMydOAhjABR5uywuUZ+pk8AxUVztNzWf3BByfW3H3QgCyMtadRm1SxOcbVJ1+peID0" + 1075 "4kDAi9AXnew/0uXrDug5gHyK+acL08nRDejopmML9PwdMOD7hekbtMr4NaCQU85CcgcvRWc9D++od1HR" + 1076 "op4Up8byI28Pef/v12UtvoRzeMbgsPKnHsvNq60TlHbRYepMOYHIUWo3l8ePacUh96Dxapn1Xk/60pdN" + 1077 "u0JEAj2HVuNDXfazrsN2/a3kmWE2JP7OnPDomlpdh+cCa3GU2wGjxoxayi53FDu9REYVQZRE6MeZ4CkQ" + 1078 "gzavBfvbeavbsUMp7MgzksjijIIRr/hWGtl0rIrkLB01dXEPNGGSgdv5QTeurfHIEufBc1Rf6Fza+rBD" + 1079 "/dm7q3mBOD9GBuyDOOdg9LcP2gIJewQu4X4EhgZ2yvq3cJSxdQA6/h+L4jla0N/KNgUVvmrFpbRhkYm0" + 1080 "87WTz2TtrGqipF4C52AqABntR6a87BjFnOkpdkspJQOUeh1oazMrljA6oamJ1ALO8Ec69HR4jeikEzHJ" + 1081 "aW+mnPIWVfOivlT9LzXxVCaLK/+llzgd/6cntTQ/lG3LvyjbDGi9z79tdYib0I3O8pGqEODqBQwsEDXc" + 1082 "fW/nfAow+LmdM9vZ5voSQDMJ+O/tHGJNZ6kQCNko6F+r6Xe6rpBPv+PVVFWfl8D0xdnKByAWJI1LaImh" + 1083 "I7Ktt8dPYJOY9XWlWMiWez/n6wuMGiSm3UO8JUbwk/DHNccvQUumejQds9Ry0S2cvbjErj4CpVZt0nlB" + 1084 "7GE/S5208FxCzKw+ca8kfu4UqMMQFm3K+80Mi3NXFj8ZcUPqVegyKZnrI2mbLBLbccPmXX18IuaB1pbU" + 1085 "qEnZdEapRdUvSdk1fi7M1gmjUSgOqXuvJtxSS7xukqoodNWFE78Vsd4hO/BT4F1j5XdbB7d+yNYl8uAw" + 1086 "VwZa+QeAv1LYJ1nvbI/hu0GP7WHpR6JgCzZphPoiRLqzazW0rh8ZV5d4b9C+yFXWjZBhETgy/7Ty/gJ6" + 1087 "c1dyFqsjh93cJBOB3EzVrdmMClt8Hz3hJRY3a0lPogiZ+DV3oLgWTdnIU8SwN3ZdOEtGs9M+dWGWIwkv" + 1088 "OtVxgNqEjz8753VfhnleYm8NfDmOzeEygysdnExz9mlIqjqnq8g/8sgl9Vm9gDcQYwatojSwXIdEvH/M" + 1089 "4zDbYNYT6sRXZ/xTdugp7ND5GfIp/B9ERcZJzclN0RFk6wj845gMqUFz4oaMyJph3oEVo8YaTXdYDN9S" + 1090 "BQYEU3SqLDQydaIxMpYTCckYD4VgLEsTORkhRiqCxs9ptoRfNd381k+ORLTGGqbmQYruwvPqVp/jyP3o" + 1091 "brGFMG0z4KlcrxE8XVdlXPlVtvJsENzzXVYqILLS3iX3UbbsNupJf7YDACN4Vy5NKn3+LmdkeBtEAh3b" + 1092 "qZaAWdEPU9JPAClbWC+ehj4eT3Vc0s2ZK35xTm/0vr7mZGHn8kqsmb8sqq00YzAl0wspua3qKoAvABDv" + 1093 "+6yKSeBatLS4z5eRCbtyWEAKpkcSoin0Ajc/8XqKYIPybx14GRczTzNzEPAvWfldhCPbkZhWH5uZXTMw" + 1094 "5FbV6TdRJ2QGkAZ3v2fpCWYRPB+sDvurAd+1js3/kb/25NPA4PDWzBXCM4PMe01ZXdHOEVM6YSnKVlPI" + 1095 "2bHefaSKE2EzZVxcjy0Q62JxlkDnXZgW91ebmCdLJs1L/gabTDz6hJZIuVY4oNRcVSYFL7O6oEZHcXjR" + 1096 "4E4hzDZvLZrbTVqQGMkQl6SbKSMRuKjKSUGz3g25557LTvWYXnMcwtlJEyn6wWJ5bp8FxdlHg0eTV05k" + 1097 "5Hy9KOChX/QP1miPfLr1edLM+2mlYcv0bc5sTQk46jOTATQ07f2MI/gYQwewMbv5usf5xSVxbozofvMp" + 1098 "EvD9A2J0dDIeMlJfmB8JHxbrCIRC6L6E6ArNLwjLgZzM3DTNHK3/CEjN+4DEzO43kcG6w/PHFMBs7e3I" + 1099 "f9XPFm8J7KvhxMIoYElmYTSodQvP9GHHEHumvoZTrIX9AAc7w01oiX/JjW7Cz6e1FaYdL0kTnBIohRwB" + 1100 "u6qeS4r9PMuEELbBBlPhQxI7TJB4tULx+gW9CkEAHm1iJXfSmNdZO85YL8XJDtzn1BhMXS0XyjjHPobT" + 1101 "J0MEiDW8lGkuuqNbL2D4rGBd1HAZ/Hu/3MQv4fl8an8uMTaeHiHhFTIEjSftPRaHEHFRgYSbYk9aAQgg" + 1102 "V8K2oKNiMb6Vn0t6f0EnlGs3phPZvnMM+yLEtwLwWJ+cH27mc1OidUzeetbOpzmBhSk6dwboiQ7k+re2" + 1103 "lG/MPj6ycz8o0XrFnxIOkxcd+lnzjSO/0IE0TpoIinfu6VP2SNpNC5oqQaf3B+iNrxAzWT/bi81zjX0J" + 1104 "N3inKxLzDgr7ecJzc/iCOF0jmnGFMunNFzad8NgfxWE/NYQfIIM6zk9jP5gijBgl7TvPhsEITB5Q0wis" + 1105 "LytkWDio1QlO0d39tI9nJUwa/9YzlYOkK/86CNQ3C6exf4iyAsm1gVJKKdP/6yBQtUGluFQTu9g9uoGz" + 1106 "XN+1KQXa2rmoXH9Ut3ySplDC3qLwkVwlbAV1z9eSSW6TW7rrGMUaOFvlCcgZ8aGjG4B9GpU0zTXU6HpC" + 1107 "4WaqmQwylBRGDpUOiLwOjDcc7uXyTHyJoeWyFs3H3gW45CQVPRWGTpbERLhGtDgY/RyC1bOr8Y5MZmTt" + 1108 "4QHchQYDmO3MzXby9OxLmDgJjg3o6ozeVamsHXiAOM/LBweL7OO5rPY9Fxxs+KAR+5ltizmY6RzgeoAT" + 1109 "Eew7mUUqYCsgeA39I1xEaIY88n+RITkXM4v7D/+/DwKvSiLK1FQU9J6WTCstcw1GTzGn76qMmCd00+gI" + 1110 "0uA0opFOhCfruU2a5E0o5/nIdo9fSy4XpSL13U+rkusjXA8+fUMgo62O4avIIek90l1+3WiaNw6nt3kQ" + 1111 "ceKn4tjStxlN+FrsKvGVmXoOX0LuehiFS9htO4bANGKoEVGLGlAgLjaAHVw+KKJ6eu170ZlVfoT+RjSs" + 1112 "llY2JRK5Z7aihvYhYLUZwVOJ4c4O7lGDQ4w36ELQhHrS+Zn0VluOioBUZ191YlFiIsWPgClavQz/aEr/" + 1113 "SoXkXcw8bN28/laL/43vYWnVYW1O8PtxuxBpxWEJdCkLsxQLqRTSp5uzf8Or+x0vpBT34Du5PLt98N96" + 1114 "/uIFduWfi5xA9rkQvCyDUVPK6dvJ2d000YplNUKczAF77ZyfddO8DG6IPztiA5W5IOUMNKScUUhBGiZk" + 1115 "LH+UeXS4Kb7NEe5e54yWJREjB711iWaRPNwHCeEvV5xNX6L5K7sAQAbpy/XYG0DO4JEzJI2EC4pBNabj" + 1116 "2h+4at+Kb22jqHLOHWRRPd3//CVovhCJp4EaUs3IGr4dvPngkfhX119emcEV5Dy11jjgFwKAFONG36Ko" + 1117 "VqB46d3p0ejDln7kW1HkA0CEsK3+h1pc3t3MxRJoKeX1B95WtU4O3JBY6XGJAE0/fHiZD4AOKXi5ImjG" + 1118 "h3B4vFgoiRmGshWar5SyIlqIYTDapSkdCefQ4wl9fNevsixM/O98/B40dlRHVkRKE8hDD2ta0SJlGhrD" + 1119 "aTUlGdO574YUAYRa8WzCvPS6eLSJuLN6NPGRaD2n3KORM2OUHSajPk1KqXIR36eR2hUE0NYkzi5Th1R6" + 1120 "BZYCl3lNX6x5qB3y7NRQBTutxZ9g2rR+HZt4Llv5kZeuk05nf+cuqGUzLaJU6FqMMJjynfZuQe+j4+rw" + 1121 "Sjm87YoTuUTGD3LLLUcRZ9e+Dx5EzuD7N1bBgQTKWOpuX0c6fHpa5pFavWSGNTdbPkB+vkcthYDw7keQ" + 1122 "jWzYFxT/0tRQMANZfb8y/0hHvo9OsmSV4PD+NlRlqgsoKCrQZiMfHI+x7Kux70/5Q2etRZ+F0TnWfFHd" + 1123 "bL3s9fH194FuJzNsBO++T0PZQiXGMVpnhJeiCtqMG5iRsHN8i9K2icq2JkVU3VWiG54mo87o0IilX064" + 1124 "EDw9kWg49NSH+RReiDWlGNXqArViQJST2AUgg289BJSsFb7T7dGPcJOGq1c8xb3whf98HBG85cpj2cI6" + 1125 "4xvu8c7yJNTydWzr7NNTHPGi4a5OGwlPxPw2gjaV1ifrosE8/UhyfgpSGaUsM1RP7+bBT3ngyxe7bBra" + 1126 "kzQfFyrvs300a8+R8sfYL5U4IyArxvJk3MP+kmgsb9P+gHTukOg1ovxoHRiUC1z5uadxsYhBQAxh+xGy" + 1127 "KH7BV9HybxrbrAYtiRt6J2kKgaujS8gOR4ubokP9WwHJg281K0opnaLXOYztxYtC0R7GlZ2LGamaaXnr" + 1128 "ejWc2fcfEmvbFlFcibNqihmWVE9gVw7L1rmg21pQMnzKQmmrYpc8VdIH6wjT44YN3CQ7M9g+HWcwSajG" + 1129 "FUdcwOWm/G5luc/yXA3ucvJ5xsa6ed1gBMlRDPH4VSbt1FKamlffvoy7+mR5Iof66OVN30QVPYCkD+Cy" + 1130 "HCaSK34IM8wbaPYYvlKLCH3dYvlEKCn8cUnM0p1Y4+ILCVd+BwEDgCVcBYp4lYH5nz6LT9/1dRiir03G" + 1131 "/6qv2ejwukIQpGyQLI//V1gdXcFAC7f7VBrg4gQGurh50cg6ujvIOrq5/K4J0fFGyve4l/piVWtrario" + 1132 "IhAnMmje7jNZwlACJgO37SaDogaH+/fL6vzLI/0kxJmEniYas0x+AA9nXqSd8JosUbyEOgBcVH1ZGe2M" + 1133 "l/jU+wzWbmh6wpANaKDMbY+R9cjKgx2gq0RWm2nf8BZ6w4xwHkmUaSjXe0YGJV1AcHryzUpgmbLjOC40" + 1134 "fdCsAN5oZARuKUZ3sJoQXrrCMqg86hpvjtrWer1xFdhwYI/c26hR8zD0OH+mjR0cP4Tey9lPnhgtHudX" + 1135 "PEVjViWwL4oh1BZmEWBgW8SnPXFxRk+0ZnxJh+6zBqIC6J8wG1n0etRFUa3Gl5bie68JbmEKjOzb1TME" + 1136 "7Pmfj2Jizi4nrlUu9p44AqBm8VecacKGeGKw+0HqH+fNG77CSxabkgjvRFdFMtmhJsUXzXdK5p/+lKx1" + 1137 "PMd8pA/ZDpv/43bIgcysf9iOETWIsnS/2zCB05DUkOQhtsBkw14bS+xI4OEMgEonVEcpU3Vupv2cMvv4" + 1138 "ZBnmK6CbEWFlVAYjI23o+nzeyer7cGthebY9ICA9gDo0arXCtJjHAIO7bdmhL3mR3G5J45xVWs11CT+d" + 1139 "chGkB9ss8sSCYYlxw7aCTH0x8jG5UhadEQduqPG2usxMPI1evTYHAc5Qj+aprxObD5nRB3+OSfjc8Rjm" + 1140 "7Mz23F0lNlMBvZMOf5TPY+OIev1sjaiKtyJp3IXgkPF8GzbE4ajsK7pOPS5hzHRA/3PQdcCp6I5K3hOa" + 1141 "zk9rORbExdyGrrxnotbf2m5pcj9HVqw3lNRRcK7PHOcVJh0KJyAE5EwrM6O0HkXxEKrhGJXDd4Mv1THQ" + 1142 "5FCUxsI9k4dHQXFwDJumLGvwsjUEj1lxEecLeEKoGhimGeeLjodRUiWQgPvd/AGi2gDanGe6/hRh0dc/" + 1143 "2T0CsvWi9iBbNQr3f9suHTOQO1DbC/x72ZSlraeOo4F7y0YmNMEl8fFCVsZWkrF3VVPGjsgucS5dzZZr" + 1144 "LBgV2EUJVApN6X13OIRg4nOmqkTFNna4HHQkTzTSqoIoY55k69J2uZm9IUx/cbpVObIENbisAYW9GZja" + 1145 "40BEzXUAPxb+dKEL1w1uh6NbFB/31LmlMuflWl7ggxgMXFQXQ02OLs4K09Q1aSIkeMbEIRvUgEC91/qX" + 1146 "N2SRkqqCMRt0SpsHFfUDHIl8WWhvQE4tUekxWhWpeM37MlrDBzGPylL3aPfCDT5VL/TfbtvGEAYl9JfZ" + 1147 "NGU2sBif2OtbnVVfvE2IoSfaxfnoxtfzkN71SIrJiYNnnUe0OV3Zxp4xIkEe5ej0dRH3oFhrEvQdOf1k" + 1148 "u4+ASxOqZl6L5ImN2nxMcoljpYFj9lUCX7zQVSYlkZpT2lOrOkuhDI3W1blhKxaXEvPyHZcxFjyVmU02" + 1149 "Y8o+zjesfufyWLtOHR77/VTSW3DEmvHQso+NZyf9Jd7wk9VqujMmsg9iJIWY96FMD3fZqbk/XcFeJVBU" + 1150 "BbA/XsyrN3f9uEjwVf1YiKnikEQkz5woPQovdOeO7ZU5qiIeP1hLlsD70anzxMgQFH/QAqozd5RxaNHJ" + 1151 "zdgH5pR+9HAQhvzwabbRUl7EZO+sOLJ5qrCwZzVbdSRb5+W36kLbuVY1fRCwJGwPAfFKZP8C3N4piREm" + 1152 "QrpJuLuhVYCKDd0YocFhSM0n1fvSFG0fZjdm5al61IqQ3juBp6q3FohPb2uLcUyCyse/yk9SSK/eum9d" + 1153 "U1tO4bBHWUhlTiz3HaNOHI5hxPXQf4tdFv+q3BilyEamscINFxL4SoRyqQTrtuUbdJ9Nsq88AB0Lk4YB" + 1154 "afzhc312hfyHqn6S6XBIfYF1iOOvEcfpFJ5ud1VS0/jTHpSO8RFqoqG91TCRznf8am8zjdYUir8IsLOZ" + 1155 "iMb03R3F6EBX6+GX8g7gt+ky2F0lQ6uWW7sKFoiJ78AQyTf2NXZ6s02Rscbi3TVrg+aMsKgs+u6nLs6+" + 1156 "nDgOLOT8vIL99Uz0v5yf30+NlpE6jiSuqLRBCjQVA5Vs9XNdfXEb1DECExo3kozntA4bAWKq87lsH4cd" + 1157 "PazDb+zFvs8taoMdSSZk+jv390UvFoQvsoVPrkZGTKDQNRoANYf97+1RnGBrrMejte23mQM20qeZBDyA" + 1158 "hK9H3xt4l1bsz8/BSqMg8DiQoVWoBtSlwHSXESibsG0kszRrXgyo4gi8vdMw/axgP6Kw9uRtHpvlOvED" + 1159 "RBZFaTl6rtfTOAp4yvW4kXkWG82osbdHWT1iHVqV3bRtW86aF9AjOzcMA+tRLqphbbvEH52nbJcvmTg6" + 1160 "Wwu4p12fvCoOmZt5vWgzi6dTMfst/NT3nP4wV9duSciCipibzQgw2lyoKNfBE6nKjvz29W7jpKUr8tXD" + 1161 "bCQvvA2E18zReQVNcgXR3ABrte04oWwAQ5UoZ1e4kD7XNnMnDPcMN+Zs1nCtES9gbqGXz9/8jdgM49yw" + 1162 "m4c0UcKlvOOKeJLWiPtb54GToW9vuqtZqzixOB1jo24MmBirhIYBXwzHWeNe6nfrUgd4ci/lEJknrAxj" + 1163 "Ji6UBi6jpK9FUAz6pL9BHag7GFMK0aUEU5RS54TyQmMcgmEzLbLaqUELUEQhPbM0SZ3TzyfgEUU6JpCg" + 1164 "bEEnwmHWvT2xhMKGXtOHmQWLfMHvUfZXgCBG3KpYc0PyGXxF2/dp6oK6CwTIepZN7Pg1P4/Yi+hmUVgg" + 1165 "t+fhP5hGIVWiDNDqj6m6qrIUJILWtExsC88VZXFZZfjf2nxU6pdAfLnN3PvmuUYlF9cwThb95Yz+Kcw3" + 1166 "jTFfGb2HdYSbn1xHBDtFT26PvsEvI8uznRuRNgrgKrAWxCg81GNCQAuQGkodVSqVclWWJrIdyM9NoX7w" + 1167 "SvtAqAyBeiUpSqIIR65WbJFxCP5jaDVLSdSGFDLpG2qLqWDyKcMznnLDLWiCC85XrwuJHm2M5MzRKdNV" + 1168 "VMBF3AH0c3VuaHEmyL7k+moRCBhUHm6AZFLCX+xtuaviNJy+0DLXrJgGefsNOT0Zsr4r+dBAP45qlUvc" + 1169 "co3v68AUZ6Ln3cp5Jlh6Ul9ZNs2OHMPeQa82ruiSpOD8IqYZyrT9Qzf/6Ac6mDRxqMhaQ7qqEIc29aa5" + 1170 "cP/gOGnykEbUh4jNs1ewP5K2+2p5YAmhDID+9UgHQvrvrcEEYfVODsyeOzpVasy6JE+vzmemuTDUibmS" + 1171 "sCFFSvlKz3O5SgzgCpGQ0QORxAhgKJ5hwGVKjqInV62fiPptCV9ef6eNmIE/zVJmMGvKcFrj1m66T2HI" + 1172 "of0koUCpmEF1t4b+WDeN/aseKg4T70txf/xObeahWkC2bLVlqjP2RmQBO4bThyDT4m9eeXkBIPmLMVWW" + 1173 "sDefuPcb00s+BM90meToqHf6PMShbe5BnV8jMmGiUqDu8sF0Viu8uJXMsCUNURdamdwox+/s/hosYelb" + 1174 "8nyejOKNRck8SvYBjeQHZWGBi13URNUDVy7QS6ZMwQbltoS9LJc3E5ttneqGGbmDJGjsywFrvEIdjxJF" + 1175 "9qh2rGwnfUlZj66eo9Z24rdkGBAxhZZXG6GZeMTuYI3x2ejiwBGzqNREWBIRVPVyCu6mUnnoJ6ZK7lxp" + 1176 "ETJMCCoryJqjn+iO7vKqhMuy2FaXfYjAf8Sq8/OY/c1N6Oy/tU4gewS0Bv7Co/631smPHfLeavn1Sr3v" + 1177 "cqqHUt14b+b7mGYtVvPS5AsF1IHzwUpXZ0kYd8AuQ9/4c28hugDvJd10LeLxt/UAElowllX3Lq3qqb66" + 1178 "xX1jSi8rtb7dYTnVo2ywpdwP53vnZFWuFiEgw4eO5nvzj49p+MmTEwq31C6hubeBag/lqQMGrgOrlbYs" + 1179 "05oHRq44m8665/E4tf3Oe9SDKiSADN8d6kitbRTgMnxUIa4nWb1V7PcOdaU0vfTtj/NLoc3qODb7cuhF" + 1180 "KBFl7e4H+M0vQciIuF8POrKgI8T1pdIcIvPJ532HHyM+Il0ebWJnwI4BuGp6joNdrtF+5MvJF8pIDWH7" + 1181 "GbIY/4GvC9gJ9NNDgL+ZGYqfHJpeKwm878h/hWxPowejh0iAUcSCxsjIqveXq+/sYffvrr5N6puvPk8R" + 1182 "wJET90YRaB7C19IZheE+AH0uHu/uPjfbejBf9MZrXoLf/SIhpKXJ6TZ/+kWYvvtF7CNfyjTbJ4IoS+ZP" + 1183 "Y1a4XoYXUgeKSCnZ53LP5VxiCFXp05KYjIZ/BfeCs004sHdUhFYrTk5yU/xax6wYkZjEQ/J7/F7kci1z" + 1184 "vpInnAgOMybUKMM/ExbxJjpp7PmSH7cil2prN3V65tkpLt4DWBr+rL7J5YxK0FQKelfb1w7IaYbxR2bw" + 1185 "s0cC1rBGwFt6MprE/zZwl9NYheJlDzPeNY5p+ymS31frn90bRoYgi/wXpJWBQPDf2yq4mbI50ExfiUQJ" + 1186 "oxFiXNozXhXh05oqz011PeFQ9qJU7k9J+rOt4smLhUHjWMOd6HvySe1Tz9a88DO+GJZ9A4EqcC8ALVEk" + 1187 "upjawrz49LnVC5xqTFR6yQouwUJ5wRedqaDCBBVLLg3X0JO2ozrz3G7WIwMbuKR4rt303DpM5wp5vrtq" + 1188 "9ARdOeWJ5dPPHJYCRkvtskJFKlds0zOLqUXeVCbDChllAZ9P9w1e5Pa+hE/fbdi6XNg0Wnp66VUi2EZw" + 1189 "vNyx4tcOaPO8zPLPt3B762hyUg3I54nPn3n3MvWMg0fnwfVKcF7UCsihaGo4HRUVzpff9L5/zZJbdqnE" + 1190 "rDzDh4SnrcF9TAR8j9+Atk9YTGJDOMtbdfHTcL4U803CvSd15R/6VipmXk7u/31AcG/GMf3djIOXolAD" + 1191 "X4PJRq6iR1dgaYvmFn7Ni3EL5Z/kvPvgN1fqZ5GJN79Zfi8aEcHEyyztTRLuNrVAKaOsBAlWTZKMplSd" + 1192 "oSZ95oABAW41dpuyx94JCTzdQht1vMwB873c5dppesoOKOUxqjVwRPIT30WCrgfWOippmmlotvkIErsl" + 1193 "anxtuWR9K4BlpndmBSncLoOLGzOdSdcXchn85sXXpDHZ38gC+iW6EzDMBtEXjQndrwW+ORC1xgAXEmM1" + 1194 "elP6VV7oqN+3V7LSJHy3Zl8OMjpDzzS9nEWroXwIWG5FeIfMcGuHBIxRbUMTOHBtlSpehQoT85WMBwen" + 1195 "v7Bgd2f/+RmLU46QIyuE7PE/DF/uXU7/mZLMMNdOiiGF54VsF725T0lyMCEpiQIB5+4ZJ9fw87a/UhLA" + 1196 "f6Qk2PLo52SkApCUhP0+JXlUcn4AF8FrAWKQBg6hRVsWSJNH16HCJiTb8fd5c5i/soStISMZgncr5SFZ" + 1197 "J56GLWsiHAjBFXCUp9PG8dZ2nZqpq8lCyeQ1jyktRDK85AbP4yaElzIHHIsnpUzZVVmaF62J1lXuQdPv" + 1198 "4bVlwuFyHfnctFTYvk+5dVFS6Z9JVx2pvPQ0Pvnob1ftoJi+Mvh6ZcBpbOY1dEjyqxmKiWcTQkZXg3Z3" + 1199 "NctQOD6rLImM6Di2B1zOMzCE4KojNLfqPolzjPZVVjacXrOML9iPhY9eYh4z5BC+EEV8z3Yu9lP2Ryfy" + 1200 "1J7kd5vJr+47VTNbx189bNE+3FvuGIGRF3hyOikRjVCl2pxOqK4s3EEL/FsL1lP0+fcWrIpV9mWvj1+r" + 1201 "P1Rjd3UkDEEYWwyhvrMxPtJifxShEA4lnj+jQsF373pisbY+27YG2wYPtXqJIQqr6+/edSRekudLXab/" + 1202 "/WHLSqv/KMeIZU0DXOf9w5ZXU3CGuNzjoc2vh6+IPp59/ZaMOpn69bt3PazDdzA/jBKDCj5MPERMmvuU" + 1203 "agSzDSkLKRm/SWXplm+eNCq3mYhAZSvJJvSkH43v8T4nx+TgUqAvr4C4vnznbFv4227HDJ/EUSkS4Wnf" + 1204 "UOnZD9nJMckVyTdOP8IVODEi/rcpoirQ0f1/enmB9NfLC9rRPx1lJZyrZjgZp1k7g9xZfb8ZInuawnDu" + 1205 "e7Cw/Z00RrKTY5xI2t6W43HT0U1zDAGRHLw6EI2Y8cb+4+UFnCNMD48F0Er1LMOmIZHBKK6axxezsc/q" + 1206 "NwuPWf5qkvDMnSSCYll+ObMNnIsAbmM/G2HJVBSLq+fH7xYem2aa0AhR/9NJJ5QkeK6k60Ppg9Gdbw96" + 1207 "Xku+ow16UY3afMx5CMeWnFaBLer728sLu2a/m75MKmZwluB7x2j3BwGkS6KNidK3BigMNQ7gSYvmkUvs" + 1208 "3CgY7cyrKJEVzEf08mp2ajE/Z2p3aIGX9/fbDmTR/wKumpmHrbXZT3PEkftpe/e7ex1+7g3RYdc/EeP9" + 1209 "qcM72NvYXrwY3x3sLpiqfNWK79KGr4u4P3+3MwhnPi32EjgD0wHIaXa48mJiFHPOy6a9X98PEku7VcqT" + 1210 "22VTiUu3eMaZRWMUiRNnWWuwG5FIJ6KS0/im1PM+quW5qXWPrxsvC2X8NkgMqY/QOjC5Q/hM/32QiNfb" + 1211 "IbHM1WxanKJVM7ho9f1BYedQICGT2GVnj7FBzuSL3PUgCpcwtRkMAR0kb1ailhjL2WSMgBF1HasaldP1" + 1212 "zxch/reqOW/35khGGGqgH6cF7YvVsj2MW2tFeOPS61T/jGoeXl604SqTHatfoD3X1SSOnjR3dX1Wcaqv" + 1213 "j/9HyOrYsvCCEMAw0L+OYDUnRzV3EOhPd40SDCdmD/2Uh0O5w42czLXA6TZ5C2K2efPU6ttm0IvAJww7" + 1214 "fElJPPF8BvulXocPfBicqcxFWQhT71Ss/DpRvw/CoR6Dt9uzYa7QSTGLT934lL3kFdRyiG3wLDWN1WYD" + 1215 "sQQiuIFdSRcfDFFpXynZdkaN2qktL7yJYk4jbt5/s9zgnq7axOXjJr3M8jK8SRKaWiYChY47c+EaIboO" + 1216 "d2ecr85nbg9LoM9JYRY0iOZCcOmu7tJsXOOzgphM3rouBsJhkOcp+npknjm64y22aec3m3ebo77G1nom" + 1217 "Cu1ODGsmlehIiJrwCpFbTcYA4xQ936JIjptVrtI/7MYwUcKiXlkg83ASU2DIyMl9le4BNFwdb1Ul1N6S" + 1218 "fjD2N/tBoW3+KuNNQIBq8dwhkRJpQ45VoWOhGXC+PyZ58Se7ZOlWOfieO9w/lIr30O8bPH9Kh3LnvSiX" + 1219 "N1RP+X2NzvnqvD1GCgE/zTdlriJFjLyaC5ooLADh2Caa333PkJUy8erIodn2hWu/iHSiXn13ICCHwZ+j" + 1220 "7pMImBafJoDw+9UKaKSn+pKwpWnZ6c0pCWOuWdTyS/blT54bkvcoMo0zhG+hbjVYqdCuVjP6oVgJI9WW" + 1221 "RGkJvjUTGLD2ScOWJKL8EAIgina8DfIOj3hf6GjzsWXGAkIesQvEorXKdryXkuDdanpJhcQkqt/ROm/F" + 1222 "8HRh67TKJ310R5/Pi3fewfnp6Jbfi6U5fOks4RiSw5w9oaDlPuqewyd7AUsaHiyrYyzh38n70Etb1EcJ" + 1223 "Z/ZyAAWGFp3OelThQ6EXebe12r+9wdfIe6JaIekctAsMR+arLpywTqJ5XWxbYm9r83G6Jh948ZMxsONW" + 1224 "7ftE8p/qPwDI3cUM5Pov9d9uMHX6X/Wf3vngInn8O6uV7yNJ1q5VbP6PnlbW2R/TBn93SHkLHIP3V2Ry" + 1225 "xNSOeYoCxmlGSXdEkoUiGfZYNvSRM2Wbqu1ktZJL0uiWUruUSrETkQzDYnbsbPGNLjO2zxMFTOKred7h" + 1226 "NDJZUX2XbSCr+/DQ/F1OvkzpkzVk71xxcpRMAgIVy7cPBxZUncVG17szQMbhubtaHF6E53B21OLH96/A" + 1227 "zQ4Jg0ntgzuzKdpUbrbH3mHABKDYbtrmbTr5iy+wqebUOwhmst4/pA3RAvF/xMdkOFoMEKZN8q8LZJpH" + 1228 "/815ibX73XmpQUeas1KwU7CxfkjyI2BMF54UUQhcDkhkk/4K8JMfrXrqWIQPZK+lwzlvWXTfvy8sRZbO" + 1229 "tERNDKhyNusfjUvItciRXp4y/AollnTERxzeR8Pm7Th/tfjp02+mGnQ0BHcEa/Rhov4gGiOZmlfmfcuw" + 1230 "e9MqZbDS1Cr1Gq6Cmsq8MbQzQpzvi2XYiRx9Buoscl85HH1/hZil7LC+nr0CkelCykCPYFwdKrUS2xMK" + 1231 "HgVzPAeQZM9W0INOoEcHgKVoHNMzI8vTwvYd/0KLUmCE+sFh9RKQAU5k3Q0svTt6Yvjy4LXfu86bF1gY" + 1232 "orfLzagE4h5PvJPNepPZTy3ji/u+xVJ07W1clF1qM9dKb3KHeuOTlhHZzTtd9HATEXkLuiY4nNDBSMek" + 1233 "+JIUeI2TIjNogsY+5jYqXybIEOHtf/zMfYx9VawvWKVZ6/Kc2pwZlnRC6Aj87aeKxa5J4OLfnoZrmnn+" + 1234 "mIlIooYuSZreP17OCT9aa8dCJxeN/v40PAB8ZBpaSCmdYgRdy+A/FCTeTgHcB8elglZpfOdtXxapvvs+" + 1235 "C1tb6AwP08Kwht6QTGCT3k19Dsuk9I5Rn9fKuxyOTZvYgPtVvF6aswxXDE5pueJq8n1Lw6pgzVbrDj/9" + 1236 "M43KFq5BugjigiV3BAsOKaem7h7DRseZ/6gfdhp4jVg/gBQVtqKGJNRbkHZgwchjMba3nH+B5Xnuaq24" + 1237 "z249nJJvCY2/zwccISPxZUPe7XrLQ6GE18z3LQ3NnkSgOd0Xf74FcpWcBpIZyB1ZBz2TRrJfoUuA2Vv9" + 1238 "uaOV9NiANae3rUMv9kZsRjmYi0kAvIJyHCytnUUqWCIoePtTCu1NhmzuAsFaAP1rO5Mm0Nnd1gXoKgm2" + 1239 "/aOzN6AGqbdD76onmWQ+XN28ffg2PkT5MVqOjoZCCV33FFQQkWaRbpGMyW8m1JFiLPxovrQJbtc27ru+" + 1240 "pTb/lrYHAh0VQawI8+gehPuUGDgdpmTkXqgnFZrxm/pyr1mERJDqZcmizCbUk1JEV0pySXutGOSWn5m9" + 1241 "6n8kHGN51dTrPxKZPS72OHY1iXIiPD87+ktYRe0TEy5LEg3sN11pqLbPWtizsYkiA+Zf9BiJraPuied5" + 1242 "MiZcPerElcYmnGGRLy+gT8J30FxUtvbJDc+JinsvriCKDNwLkWjWdidBC/18GvqsJ1YKxzPOuDL4fRRe" + 1243 "y+m7fcSDPbzQvj0lsAYz97pSfYbc8lJKYLq6prVxodIrtUVWo6Yt2IOij8KbBE38muW8zXmFJYzucfHh" + 1244 "cPChSPqbOOqWNkyzdS8LsjY6OnBpBZnUJ/qNqeS7Bpdgp6yGjFKlb/fkaznUv8AxWcPiVwcDE8Xa8XU7" + 1245 "XiPZ05VlVJm936T/cdMYbbuGeH5/wPerPtQfmyYHNHNzdwH+WWveFz++kSFMXwMiiDHk8pE0MFwOt/tM" + 1246 "w+lsFA1Uol7BydUUgOpBf9bxKUEKUqtmSy1Dg0+5ha++P6rBfsrGxOZhuI8soI+umOPiPU3aW132QfPC" + 1247 "Plcx+cAEKUnhHY3ti9CCaAlOFa42Hm0Q3oNWIFOhRlBBn+bbKpeAm4cTcmg7GtHa9EX25TjU0UqnCsvb" + 1248 "6iiXGcVwlrPZRPyDscDM6qdnL8d1sEsPguFCRp0Q3NWXTaupEmxfohKQsw8/PTp1HltPbuwNz9bfT3Za" + 1249 "8Boi4Xt3kWfwUrHkQDxYY7RC3u8hmMqdXVX7i69fXZM7YpL1zfXws7ct7Z0h1IMe2niYvUd6q/79giIY" + 1250 "x1A9gdGZzq8ao/BitgYjqvyDH5WZLY5bCwSjJbGC9Gdrqm5+Gtcz1/Bas0Gws0DOC+e/oAcAXRxsXe9N" + 1251 "+DSaf9af0RrfqyRfuBQ8Gbh3z+m6uwih0xsRYo1pamSwUS1pjUXwCBUVd3Y9Xmz/4QGyoKJzWeY4Ecqa" + 1252 "aeP/LYdX1jbSNtx/O4sD3tSkpwHrOLkVEsnnEr/zHk/lSKlGjiYYVc6jqvGNsOrX//QWu5jHH4nVOyE8" + 1253 "Bm63lIL9U5giT17DOIvhjXpTan8TrgAiNk4pkShDaWg6frrOcnGGiwjr0HrlgoQcToTeqqXX0gwPNQ7G" + 1254 "p+xwRbXmNU8D6Ethf/D8mmzuEmq64deASN+Akyk6ITSFGDgXccAuofRYdMo0Ngkru89pqBbxkTIZe30D" + 1255 "oXpOQzpYVeJhZ/yGE55gA1RYqcjjYV7DUJZpAWuARPxRXMYeaZO8JRItqMCWW9VgdsUPaycECJpB/sm6" + 1256 "tvhs8YDjd+sK1/8O/7GLrRvwl/QDu3s78gnCWeJhYfTCye/p9zk+fmOU9/vNkKkaldob0Nkys9NyPlT3" + 1257 "vd/NBnDXcK7+bC7fntb3kDJg4pvi411n0pIje2k7Mj3bRwUkYq00THQTrwS0uw+nCyUKL5ltxhJVoJkB" + 1258 "JrdPjtiUVrHqH7V3T90lnJRkKgaIio/phLhVRhHD81zwQCMsak8gFmRf15P0PpFKYY3Bn2l9JjXucXiu" + 1259 "wuIyR1Y5j9275B2UQc6OfFO0tN51YrSPnMnKP3YkXcaivnoNLsnn/TATwBPaOHXckvgJrETtV9oZMjSE" + 1260 "gFvMam2Eg9kLtry0kFV7iBBWK2I9jGdYxKJDyM2Q09sy8uFRzAJ1TTD2tKauuhmMgSE7VWtV1JD+yk/p" + 1261 "D3OYEfoAhL8WDOQA/M/8fyefoOqEw4kZasKv+KIObm5cEznJrxI7oDeA+tWjGrx4Kb45FlkehPUDNerH" + 1262 "MQTn+VT+0TDizyhCCKmVciJkMMjn16y7K3tObnpmnKCMO9yrviy3d+QGUQfMXang0VSN84bWNKR4qTUF" + 1263 "WQTYKXCZLSvtJgREy9V6MlZaKitzO6JFqqQd2QfwjqTWxYUoqYaxWZagPAAnTQo1Ys6CeORP3tuNq3y+" + 1264 "dMlMl/loUwLHFL2pF/LIJbDQTN+KM4thyNMp5LRJm2gDpp+OaYTI3zYRGRRWyDgZrPaoYph3qGsd+srf" + 1265 "iOWOtE7I1lCtFzepKqb1UkUBDqfFvOsGg0uhPuLVuernbH5S5P1BjOeWfEWBTUGXW210zMzpflShB09v" + 1266 "/DC9NPi3/aPEUH0CPrzxO6XbBg/NSfoThnyZ08A8Lqc3etfz6Vs7iqicz3nTOI3e6wT2O+Q2PemAqbSE" + 1267 "5esE89uWxaZVqxC8J87N+/LvhPcuWZ3nHSuWK02WzZpz9Dcem4V7DrSUruua9RgtNHtEEa5ILbqVmX+e" + 1268 "cw51Hz599gJltn2z8rZymXLEIGoSKbYqusdDUCr6EFa9/GP1Zhpv8/S+WTzMtKDsFF+DQVjnCdmbW5wf" + 1269 "gyKsq+ViC3IgM+CgoJh+GRSubi62Fm7aTjRaFk5/mGCitc3U5wC4oslSKCklz9VGS1xBgY55GY5qqYHP" + 1270 "Q4OLcxXkrk2Z3CrgDWA+sHxUn3sR3mfYADo68ZusucqOlrJCpV0Y2Gm9aHH98jRW3N//Gv4Q2cD4ue7x" + 1271 "Cu8nhdSEw+mwhzqpir2ExxocHVwJXFKD7xKxrPwedTOc2HPRpar3pVqKsZoZPUsaKScYD6mBeqNfreb+" + 1272 "QGmY58y7qIiX2Fu6vbbFSmcvReMGd0ZlooZ3vmrwiaTTrHu+OUE5Irsy4qGwCoJBSFar0YMOdJ8qg17H" + 1273 "zU8ocZVmjtLPnKTFy/fwhqZLoaVCimxJ6L37bAjDeEV9a/FtCYcp7K31W4rS5I/mifUnjAZfyyanTrae" + 1274 "qYiVv9aD1ixIGv5SbTJxtRhxkWlbT2fPjx/tbkRjVcaEVsbulPrN42QdUEnAm6CGLDA/jPCAeYxvhwkr" + 1275 "VT5c9811QMujMTvackcO/TADnnqcrA+3a4VsCaG2s6U8VcIpQx+UtB38eYqVK+1I09IXy3ASmfuhXWo0" + 1276 "XSNezNvVWp3QfMz6NAU7j1CqV7mdAa8155nB1UOIJ2LV46EkCU+CXQNNtYjJnNpdFLj1JNcUkRpZajA4" + 1277 "jQhoFZimGIX4ZLQkI0a+0CqtgIYwuv6szvVJ2WOQprDf3TF0ylxPr5PMasXnfUO+eP2cebwCZuZCKRVO" + 1278 "CbH1r1VrikLeHPDnInmVCAVh8nSZUYqbV50gG1yClQ84Mgx7jLmMx/tH9Q99pEfwDE2QxoDuqc/w+l/K" + 1279 "TfaZFNTPGphIZF6iX+DJpCxNxFNQlxpam8HXiqhJ0w8Q4i/nYZzxcAt7II1cim5gb6a6dXkNi1gyZXsG" + 1280 "++TKzZ5c0ne5SLgYSbU9ewHzsleSHSEiA0YcAUOE9NR5lN2Zo11SYtO0aukkMqdUFqGZpWG0NGWR9etU" + 1281 "zasQsXqWeo6clA18+CkUxC3+RGL6knbi697xtmKeSt/0pFAeVJCWMturkBenWwPXVOTHO6O877lCtXL9" + 1282 "fzwupLHYC/d+P+N/eGTz13H549ZSvk/bsjceweH6RHbLo1K6xAd9apmdfN01h/02nRDdipEEkrapNmP+" + 1283 "8dSchQ4bJ498M4O9dknEY/Nm7QwNSs1s5hkrTANaMWGV9MM9hDFuegBIqc+C2VLxPQ5qrJ7Ae/BN4yfn" + 1284 "1P0P8dutPKlJ8eZKMjVjm+ERsjk22lk6AvRxF/kapIfMWObmtnQCRFWc1ADb2AJs6duH2GNoTZdGKPNk" + 1285 "QvoTiGn7d6C8xknU0pnbuLo8ACwOrhVrz6kv9NMTHIbIK8PcA5vbZrJjSp2CxJ2XSkV73pMFqiO+ebGs" + 1286 "GRKbAxsHIO81I2wG3ey9ifNW2VY+vnd2c+hy0Sm2i+kzDAt3vk9h+2s5Ww6eIUS0dyz0WZFQA25GVO1g" + 1287 "EQtGx594JXSUmD7QI8bH0ooLg/7GbSk7SUiaYkqklO7xsCcXlZlYh7fMVnemKtcMxyU1Td4WnvWpxuVP" + 1288 "Hgfu9RWUJ5C9CYP+9dRRy9b7T3/D913psQ4IxKT4Co/nlfrb2yc8pWBtJSVpc5E4OJ2aAgxo1gfs35pE" + 1289 "vj64BuyWYWwHdIkODl9vvblx8vh2P7uBegzGDzJEPeZkwAQUDR4LBhxeyma187mTzlhkg7OQ/S3bNhhf" + 1290 "vkPBMhDoR7lm0atJO27ZrvioEBn/IVk8UCJv49saeSUyCtkq61EXexioH7EAbekoeGjenOotvslbNcR1" + 1291 "3r4klk1UJdAYw6OFbCfXnrUbe+imqagOURoO6YKvGONurGMZ1MVJvHN2WL1lYqY1R8+e9uLpXDyKHLBP" + 1292 "O8GSZ/hUAN+qpTr1sKpkB/jafW6yeIxElRbzQ3e5seSAneoUeCkvOtRRs7aIX2jTFyce1/WbxeNTa0mU" + 1293 "SzBsgvLTVuF10VgJj43olEo9GoFXcZl4w9TYlJgP4EoZdFaEugDPEUJgkfckzWBCynPiuio/mxIHGs1e" + 1294 "3b54XxV79YAKCz0sLrBOhUJiBQzbw5XZGxe/oh26T/DjntWBR66YIHv25R+mmVqQ0/T3iVucujK0JGH3" + 1295 "y7EpVuY7bXgsDTfM1u1cC3rGoIeGem8einYVO3FxDfcLMV9OCZ0++AYYa5bZldzmGLzauhD7Mvjbfy1A" + 1296 "TM8WY0jazIBiia/ZQwOomP4Wi9MUh8Y61DhWH8+1RhKgOfGbJUjeiWtapx3J2hJ2fEqffSgQs9e9U4B4" + 1297 "vHWcJfmOzKolGxE581t1tZ3SiF0FfPp0hGvAQHShy5TNV8s+Gizx3GOMcaR6YjaiQY9W+rsGWnCbL1Xc" + 1298 "2P/TyZnHQ7X+cbxLyF6Wa8u4jVA0LYRBlnCt5SIhSyFLSM0PKaKSUtYyZIukyIjURGXrlp0bEVrppiyp" + 1299 "3LRIstTPzNCjr+TU+KuX13mfcebpzMzz/XzeictCrNpGCOs3xHPFKzhRmrZfu35aZM2e/+53ZMbWGimE" + 1300 "aysGPFloE2R5utDyAyu/6OWNQrZCF8Qp8/xWVMmsku++dK2WFN+97DFbYYfT84tNFcvziw5V4gY/aXT2" + 1301 "HmjjWXSMKdzwwZE/4khD4LsPXjbh/GyDY8alnq1/+fToYrc/dk/pX05Jl1yipUsa+kqVR6QZVxo3IXEQ" + 1302 "oui7n6pqvc/Ovhp/0l2B153evizk8mG0L7PYDbea5+SaNBh1KJGSTc7Ul569qpuVUP2JHJn5MOTmeqr0" + 1303 "4lsct63NN+Usduu/p9lslty7p1O0ODgSH5zzLJT6T4/zpt1W9SPsRW+rTyo7mX14KKHJvZfpSgyXlObo" + 1304 "cfFhZs0OG0lhP5c3qjFPtTRYNWxlFW6Zq+/9MvLUz42pIbWTVHz6AYedEA/V1hn5D6s4zi9ss/tAfK3A" + 1305 "6D0lMHL5ZdSQcyEwly+2YaHybJ35Db7+U8utP+zMJ0wYEF2mGhB/JJLTc78amZ3Fzd6KL1kl0DyhQHQN" + 1306 "u8sp+urEKWGyIdnGZVcyw3UWZeRKd521EG1NndwDZEgnGg85Jzkci2m2SWKU5rNpAk9fJpE/mYQ+sUhe" + 1307 "SYlxeS2t2S822du7I6HOVcx0Ip1+cdUGhvfdpAas7K3t8F9W8Xcpb2Cwz4l1Cdmn/v489sbNhSnKq6LM" + 1308 "2YQqWFif6lhSc+6AVnA/TztDQfLwKvEl9XF3IL31lDpyCJ8eWhzLTGs9AVnUy9OXXtG2xp//QHVGv7oz" + 1309 "1ocPShw+/PYsCke1LxDlzKdZHIokL01ZvumTy1dCjd5xwJFePK2vKDrCGewR55qTGPDouJbkZVsdD6cl" + 1310 "Gbs885SMOmTr+XKEVt/zbDi0jtwqm9PiTCAJEde3UZzvWe7XLTlZ/fAgn3GLfnBb4HqDeME+akaBmXTn" + 1311 "YMP+jIrW3j2v+FRp6/fV6KEYm4bay6810j5yF73Va5OiUkafHTvFZh/8j2koWWJfrXhAkGaHNUHY1/mN" + 1312 "UrzjFg0Wjf36Ui0bz2f1j7B8vC9t+kRRfF2PgG3wyXYVvxJ6Ogp3M5Up/Ib1RDpKp0fukGw0qa/dSoBd" + 1313 "hqJC3GW6u2kIbCVm5iicXjB+eVt/MNO08Hbc4eMOZpqMt9EvnNosW45uXiNcxRwmpLJnoNUgTDqRnBnw" + 1314 "tqCAn/7hRurdXfq7aPUm3jOG/MpJNbdHe2I+0bNRUVt5j+CKcdFzH7Xk1m8VfRE3t9gsb136hduRGc88" + 1315 "0i2NOnTjq19Kqb/QbjR/F1WX622wqElMzfW4rIIEJa3SIbGqe/we0aXXUZocQ1/F1UaZUo39X0JMLlvU" + 1316 "eC7fZlKh7y82L8XSSlc2LdblzRlViYyuwYh7K7qK1efesScKbFsf+OK9zPHSll4NYZ/crHVkN1X/sZYv" + 1317 "H1Pnqp5c9HT7WqogMSelRGXzFq3T1eZH9ipuD3rFmrx9hcr4yu0JjGiq5vFLHYlUdeQdMREn3v0E+qY3" + 1318 "5JmlF07sfc90W9joPpOf78zEbcGAF6euaErz8wlN+vkMp/j5wp6lh53sU4tNcht8XE+PQ3kuVCOSSL0d" + 1319 "R5GgTz1+VEomZsDVSUrYpFzbXSVLvyguNm5NpjyhoL6V/NR7m4iyoMfL8CeharXPnEyMNnhXkMzodj55" + 1320 "up0vctdHCd+4TPnNbcGfmyLwofnvflv+binNzvdxLK7v41DA2gk738qC4TKdyor/pbEt0jmhGRUYWl3L" + 1321 "qa4zdM5X1oLsJu8/NvKgsVhYVSzfQf6stUJKwvBOvwcuDpTEEpa9spR9nty7+Peee5lY6DXMrc1P6Hsw" + 1322 "ILJRW6zEcjDXN7cPpoej3pZWaYxfV7bxz3tyM1xbS3cf9/Fbgt5Ob4vxT+XuX/VEZvQtcHWdMo7wA7wC" + 1323 "9r16Z8Q2FfrejXM6Oje5+ZIicyQxwyTWT2tMUWjfAQmXUp3I1Xcqqxrqi57XJ40MMRYtv5i+kqhStMh2" + 1324 "zd7olKatDvahl8VyLHwy9dfYzItoVQkN7y/cffvC7i8ERfeI9F62kCYfnYtefP6hgfubtsSw4LeOLSG7" + 1325 "JXGwvnpGzvWMNqf22FSfJ+CG8M1cmY6lBtJnJCXJd/XlT3Qa+D5bLJAd7+Gn+Nz4dtO8341uybxtuBhk" + 1326 "Hpp/6k4BPs+V8FmngCn9sPw1sdDy5oHyplH9lzUxKaXJbDsaRXhEbhclS1NT/nbuvhHuTMkLYussSjTd" + 1327 "mrV/35W8UsNOvehybRx3ONNj5frCtRFlrqxC7AnyeyLe+LEmlG0bVKOYnvNQapGKWOgh5y2015c8d0SA" + 1328 "jWnXNLcyd01D+GwaSqud3p5YNJTjyzyzmtmmOU+Uvsytr55De9n3Q0jb6KXfnqRj9fc/1sgcMP52lV8Z" + 1329 "X+XvE7svxr1PSNFtTgvLdCCyc2Z2p+C6tE3MvU/8U9Akv4Ez9H2MC2u2aUvwkDFX6Ca7ekN3ozzh4u51" + 1330 "Bo/mVysYeC1tLo/sHwuJzreolrPtiGpf4kQkrOjAp5GV2v/0//evurwaq53Op4cvNO48uEjnFudrPO7f" + 1331 "vWvmiZwfde9TWF29o1e0XDk9z9TwVF1XUP7DnjrhR6+Cy5z1qK5EuceOQTU4Zp2qUcIDq7UfrDwpYm3K" + 1332 "ZjUPvGJ3zk/e5lhT3Ejh86O6uTwxajN6DqqUdvgaG9wsAzRrr+9aKL+6lafYeCorQ5beOhS3zJ7JHj+5" + 1333 "TeqBx3218TBuIWgqvMag2UVXXDxWq9sdd6TAo77Vhj3lcDY1wETyenPnhI3HVYokTjwnIqfgdf6Jbn6q" + 1334 "7ouUyMy61JsblRjaag5Pwaz2ws+8j/6ia6vljocE3/zTr8yUkOWcVFJ3e2RV0dvQkyyrLAIHjvBev6qV" + 1335 "vYKhrU7NkyDlig7YyO8Rqbsk18+8pcMuqU7+TuyEXPmq1316yiQhiX/7NdoEjTYTVum6MZkyKaGlTCgO" + 1336 "jUWNtfyDZru8OzJ6ptl4aI9JVTvfnCmCeJL3Tjdaj3qaqP0vk0CHxDmMBrbsd4+YfH0I6PXxWT7+2wtN" + 1337 "xhzlWlysHWMpeGOC33LTpfaFC8rU1qkt5Tbhf6Ere3T3Ncsyt90N8nVf1pJx84/JCR0cML+XZa0i5bjk" + 1338 "qGDJo43zooNkuhrvrYqI3loipi19XT89MVlH0C7y+E2purweqvrVlYMZ6yO8wuwDvUSEPWxsr1GihhLd" + 1339 "XHkuSHPlO1ZmfCq3KRl9d6q5f/+TFzfe6A2eseWpHPIf5jY1/o1JgHlmzz3jMX/Of/Rfff174WHQtT/5" + 1340 "yAheOuf75n3sJ/abuux/dJjAN4elzTTlBwQo30dPvWUGwjcqfoiDunmEo0UPMMnnIRL61RGSzDy7bR3S" + 1341 "oFIc0f6bi0kwDoHQo42AhqxYrNqQB8XRiEdhw6CRhjioSkY4Fnas4mTIhHJgxHTjwKAKhjjow0W4Ck5M" + 1342 "dlwIhJ5YBBzlwmiNhUioREVIZ56fFKRCNDR4IvT8+Vh8npAHnZWIt2MBJoPltBUJHI0I2MiHxdgIedBK" + 1343 "iHgEAYyOQoiE3j6E3CyIxeIHedBUh3ilv2Py1kEglKYh4EFhjAo1iIReMYS8LILRMgaRUKSFkAJi2LRa" + 1344 "kAiVTojYvhCD4AnioMQI4VRwGJVGEAm1PQiZLIFN4gOJUFSDiMN/YNLWQCAUtiCgDh6TvgUCoaEEAc9K" + 1345 "zuorgTDo5Zjy5y7+ZUsHPAm0TaCThEn/snsCngQ6EtBJiEt+2ZgATwKL5Ogke+R+slYO0bBUjNA1hNkr" + 1346 "xpAGi7OItmoFlhot5MGSJ+LdXYmt8gmJsNaIiIryP1FyhFjY4UPYNIXZGn2QBTtriDWyGlODDQJhTQsB" + 1347 "NylhKG1BHGwiIVyVMrZeEiTC+g0i4lUwlHEgDhZOEG6/Kub6CYTCggWCdqlhqFtMe5FBbwDh7NSxtAim" + 1348 "3exAHH7K/xQNbOF4SIT5b0RU0vpxGnzaXQFEmhHpwtrZA86QBlO8iDZPB2OmFyJhxhQhr+v+ROIUYmF+" + 1349 "EmGJer+QpoR4mBBE+Cv6v5IXnPb0QQIO8RUNfy4PB8kwRoXIRsY/E6qCXJg3QVx/E2zpE0iEKQlEFDSd" + 1350 "LTMBWXB6j1h1Zphm+RAIZ9QIuHoDpok1BMKxLAKSLbAMaSEPDiIR781GrGNJyISTN8TcYIV5DgehcPCE" + 1351 "oNnWWMZQkAeHLYjHYvNTo5dpX1rB+ACBI22xDhMgE26YI+Zru9m3z3+0vcj3lUXbXjTa/L3t32nvs2DD" + 1352 "GD2bwO8eP9P2sakxCyvtON3xn6zxL/R2W2j/+j/MR0DQGXUAAA==") 1353 1354 private val SUPPORT_ANNOTATIONS_JAR: TestFile = 1355 base64gzip("libs/support-annotations.jar", SUPPORT_ANNOTATIONS_JAR_BASE64_GZIP) 1356 1357 val library: TestFile = 1358 mavenLibrary( 1359 "my.group.id:mylib:25.0.0-SNAPSHOT", 1360 stubSources = 1361 listOf( 1362 java( 1363 """ 1364 package library.pkg; 1365 1366 import androidx.annotation.RestrictTo; 1367 1368 public class Library { 1369 public static void method() { 1370 } 1371 1372 @RestrictTo(RestrictTo.Scope.GROUP_ID) 1373 public static void privateMethod() { 1374 } 1375 } 1376 """ 1377 ) 1378 .indented(), 1379 java( 1380 """ 1381 package library.pkg; 1382 1383 import androidx.annotation.RestrictTo; 1384 1385 @RestrictTo(RestrictTo.Scope.GROUP_ID) 1386 public class PrivateClass { 1387 public static void method() { 1388 } 1389 } 1390 """ 1391 ) 1392 .indented(), 1393 java( 1394 """ 1395 package library.pkg.internal; 1396 1397 public class InternalClass { 1398 public static void method() { 1399 } 1400 } 1401 """ 1402 ) 1403 .indented(), 1404 java( 1405 """ 1406 @RestrictTo(RestrictTo.Scope.GROUP_ID) 1407 package library.pkg.internal; 1408 1409 import androidx.annotation.RestrictTo; 1410 """ 1411 ) 1412 .indented() 1413 ), 1414 compileOnly = listOf(SUPPORT_ANNOTATIONS_JAR) 1415 ) 1416 } 1417 } 1418