[
  {
    "path": "README.md",
    "content": "# Awesome Android\n\n> 该项主要用来收集和整理开发过程中经常用到的三方库和控件，并包含一些演示代码。[可以参考下文来了解更多的内容]\n\n## 代码清单\n\n### 1、整体结构\n\n```\n/-----\n     /----- advanced           IPC, AIDL\n     /----- animations         CircularReveal, TapTargetView, Ripple, etc\n     /----- client             整体 APP 打包\n     /----- commons            公共库\n     /----- eyepetizer         开眼视频, MVP\n     /----- guokr              果壳新闻\n     /----- knife-annotations  ButterKnife 注解\n     /----- knife-api          ButterKnife API\n     /----- knife-compiler     ButterKnife 编译器\n     /----- layout             MaterialDesign\n     /----- libraries          指纹识别, EventBus, WorkManager, Knife etc\n     /----- live               全民直播\n```\n\n注：各个模块借助 `ARouter` 实现了模块化开发，可以通过修改 [gradle.properties](client/gradle.properties) 中的属性来实现各个模块独立打包\n\n### 2、视频直播\n\n对应于 `live` 模块，该模块主要用来演示**视频直播**相关的功能：\n\n基于《全民直播》的 API 设计的在线视频直播功能；使用了支持包里的 `Palette` 来提取图片的颜色；`MVVM` 架构设计 (在该项目中的使用不符合规范，谨慎参考)；使用了pldroid-player作为视频播放的工具。\n\n部分截图：\n\n<div style=\"display:flex;\" >\n    <img  src=\"images/1_0.png\" width=\"24%\" >\n    <img style=\"margin-left:10px;\" src=\"images/1_1.png\" width=\"24%\" >\n    <img style=\"margin-left:10px;\" src=\"images/1_2.png\" width=\"24%\" >\n    <img style=\"margin-left:10px;\" src=\"images/1_3.png\" width=\"24%\" >\n</div>\n\n### 3、果壳新闻\n\n对应于 `guokr` 模块，该模块主要用来演示`OkHttp + Retrofit + RexJava`的开发方式：\n\n基于《果壳网》 API 设计的新闻客户端，包含基本的\"列表-详情\"结构；MVVM 架构设计 (在该项目中的使用不符合规范，谨慎参考)。\n\n<div style=\"display:flex;\" >\n    <img  src=\"images/2_1.png\" width=\"24%\" >\n    <img style=\"margin-left:10px;\" src=\"images/2_2.png\" width=\"24%\" >\n</div>\n\n### 4、开眼视频\n\n对应于 `eyepetizer` 模块，该模块主要用来演示**小视频**类型的 APP 相关的功能，同时演示 `MVP` 架构模式在 Android 端的使用方式：\n\nMVP 架构设计；基于《开眼视频》的 API 设计视频浏览客户端。\n\n注：项目比较小，功能比较少，主要用来演示核心的网络视频播放功能。\n\n### 5、MaterialDesign\n\n对应于 `layout` 模块，该模块主要用来整理 MaterialDesign 相关的布局和控件，目前包含的布局有：\n\n`Navigation`、`Tabbed`、`Bottom sheet`、`Scrolling`、`Collapse`、`Support 28` 中的部分控件。\n\n<div style=\"display:flex;\" >\n    <img src=\"images/3_1.png\" width=\"19%\" >\n    <img style=\"margin-left:10px;\" src=\"images/3_2.png\" width=\"19%\" >\n    <img style=\"margin-left:10px;\" src=\"images/3_3.png\" width=\"19%\" >\n    <img style=\"margin-left:10px;\" src=\"images/3_4.png\" width=\"19%\" >\n    <img style=\"margin-left:10px;\" src=\"images/3_5.png\" width=\"19%\" >\n</div>\n\n### 6、其他\n\n1. 自定义类似于 `ButterKnife` 的库，文件路径包含 [knife-annotation](knife-annotation)、[knife-api](knife-api) 和 [knife-compiler](knife-compiler)\n\n    该部分内容需要使用 Java 中的注解以及注解处理，你可以通过这篇文章来了解这部分功能如何实现：[《Java 注解及其在 Android 中的应用》](https://juejin.im/post/5b824b8751882542f105447d)\n\n2. 使用 `RxJava2` 搭建一个 `EventBus`，文件路径在 [rxbus](commons\\src\\main\\java\\me\\shouheng\\commons\\rxbus)\n\n    该部分使用 `RxJava2` 实现一个类似于 `EventBus` 的全局通信的框架，相关的知识可以通过这篇文章进行了解：[《RxJava2 系列 (3)：使用 Subject》](https://juejin.im/post/5b801dfa51882542cb409905)\n\n3. 在该项目中使用了 `MVP` 和 `MVVM` 两种架构设计方式，同时使用了 `ARouter` 来实现了模块化开发，你可以通过这篇文章来了解相关的知识：[《Android 架构设计：MVC、MVP、MVVM和组件化》](https://juejin.im/post/5b7c1706f265da436d7e408e)\n\n4. 如果你希望了解 `OkHttp` 的源码相关的知识，请参考我的这篇文章：[《Andriod 网络框架 OkHttp 源码解析》](https://juejin.im/post/5bc89fbc5188255c713cb8a5)\n\n\n4. 如果你希望了解 `Retrofit` 的源码相关的知识，其中使用了哪些设计模式等等，请参考我的这篇文章：[《Android 网络框架 Retrofit 源码解析》](https://juejin.im/post/5bd05d5c6fb9a05d2b6dfc46)\n\n\n"
  },
  {
    "path": "advanced/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "advanced/advanced.iml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module external.linked.project.id=\":advanced\" external.linked.project.path=\"$MODULE_DIR$\" external.root.project.path=\"$MODULE_DIR$/../client\" external.system.id=\"GRADLE\" type=\"JAVA_MODULE\" version=\"4\">\n  <component name=\"FacetManager\">\n    <facet type=\"android-gradle\" name=\"Android-Gradle\">\n      <configuration>\n        <option name=\"GRADLE_PROJECT_PATH\" value=\":advanced\" />\n      </configuration>\n    </facet>\n    <facet type=\"android\" name=\"Android\">\n      <configuration>\n        <option name=\"SELECTED_BUILD_VARIANT\" value=\"debug\" />\n        <option name=\"ASSEMBLE_TASK_NAME\" value=\"assembleDebug\" />\n        <option name=\"COMPILE_JAVA_TASK_NAME\" value=\"compileDebugSources\" />\n        <afterSyncTasks>\n          <task>generateDebugSources</task>\n        </afterSyncTasks>\n        <option name=\"ALLOW_USER_CONFIGURATION\" value=\"false\" />\n        <option name=\"MANIFEST_FILE_RELATIVE_PATH\" value=\"/src/main/debug/AndroidManifest.xml\" />\n        <option name=\"RES_FOLDER_RELATIVE_PATH\" value=\"/src/main/res\" />\n        <option name=\"RES_FOLDERS_RELATIVE_PATH\" value=\"file://$MODULE_DIR$/src/main/res\" />\n        <option name=\"ASSETS_FOLDER_RELATIVE_PATH\" value=\"/src/main/assets\" />\n      </configuration>\n    </facet>\n  </component>\n  <component name=\"NewModuleRootManager\" LANGUAGE_LEVEL=\"JDK_1_8\">\n    <output url=\"file://$MODULE_DIR$/build/intermediates/classes/debug\" />\n    <output-test url=\"file://$MODULE_DIR$/build/intermediates/classes/test/debug\" />\n    <exclude-output />\n    <content url=\"file://$MODULE_DIR$\">\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/apt/debug\" isTestSource=\"false\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/r/debug\" isTestSource=\"false\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/aidl/debug\" isTestSource=\"false\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/buildConfig/debug\" isTestSource=\"false\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/rs/debug\" isTestSource=\"false\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/res/rs/debug\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/res/resValues/debug\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/apt/androidTest/debug\" isTestSource=\"true\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/r/androidTest/debug\" isTestSource=\"true\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug\" isTestSource=\"true\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug\" isTestSource=\"true\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug\" isTestSource=\"true\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/apt/test/debug\" isTestSource=\"true\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/res\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/resources\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/assets\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/aidl\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/java\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/rs\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/shaders\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTestDebug/res\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTestDebug/resources\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTestDebug/assets\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTestDebug/aidl\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTestDebug/java\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTestDebug/rs\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTestDebug/shaders\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/testDebug/res\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/testDebug/resources\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/testDebug/assets\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/testDebug/aidl\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/testDebug/java\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/testDebug/rs\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/testDebug/shaders\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/res\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/resources\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/assets\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/aidl\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/java\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/rs\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/shaders\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/res\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/resources\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/assets\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/aidl\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/java\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/rs\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/shaders\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/test/res\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/test/resources\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/test/assets\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/test/aidl\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/test/java\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/test/rs\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/test/shaders\" isTestSource=\"true\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/assets\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/blame\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/check-manifest\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/classes\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/data-binding\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/data_binding_base_class_log_artifact\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/data_binding_base_class_logs_dependency_artifacts\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/incremental\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/javaPrecompile\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/jniLibs\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/manifests\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/prebuild\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/processing-tools\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/res\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/rs\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/shaders\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/splits-support\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/symbols\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/tmp\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/transforms\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/outputs\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/tmp\" />\n    </content>\n    <orderEntry type=\"jdk\" jdkName=\"Android API 28 Platform\" jdkType=\"Android SDK\" />\n    <orderEntry type=\"sourceFolder\" forTests=\"false\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:documentfile-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:print-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:support-annotations:28.0.0-rc02@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:interpolator-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.crashlytics.sdk.android:crashlytics-core-2.6.2\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: io.reactivex.rxjava2:rxjava:2.2.0@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:versionedparcelable-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.github.CymChad:BaseRecyclerViewAdapterHelper-2.9.40\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.squareup.retrofit2:retrofit:2.4.0@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: commons-io:commons-io:2.6@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:support-media-compat-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:loader-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.github.bumptech.glide:glide-4.7.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: __local_aars__:F.\\Codes\\Android\\Projects\\References\\commons\\libs\\pldroid-player-1.5.0.jar:unspecified@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:animated-vector-drawable-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.squareup:javawriter:2.1.1@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:multidex-1.0.2\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:appcompat-v7-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.databinding:adapters-3.1.3\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.squareup.okio:okio:1.14.0@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.google.code.findbugs:jsr305:3.0.1@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: javax.inject:javax.inject:1@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.meituan.android.walle:library-1.1.6\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: android.arch.lifecycle:livedata-1.1.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: android.arch.core:runtime-1.1.1\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.android.support.test:monitor-1.0.2\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.crashlytics.sdk.android:beta-1.2.7\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.squareup.retrofit2:adapter-rxjava2:2.4.0@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.google.dagger:dagger-android-2.13\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: io.fabric.sdk.android:fabric-1.4.2\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.squareup.retrofit2:converter-gson:2.4.0@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:slidingpanelayout-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.databinding:library-3.1.3\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.meituan.android.walle:payload_reader:1.1.6@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:cursoradapter-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:transition-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: android.arch.lifecycle:runtime-1.1.1\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: net.sf.kxml:kxml2:2.3.0@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:coordinatorlayout-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:support-core-utils-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:customview-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.android.support.test:runner-1.0.2\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.alibaba:arouter-annotation:1.0.4@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:palette-v7-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.jakewharton.timber:timber-4.7.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.crashlytics.sdk.android:crashlytics-2.9.2\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:drawerlayout-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: android.arch.lifecycle:viewmodel-1.1.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: org.reactivestreams:reactive-streams:1.0.2@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:support-v4-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: org.ocpsoft.prettytime:prettytime:4.0.1.Final@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.yanzhenjie:recyclerview-swipe-1.1.4\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.alibaba:arouter-api-1.3.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: joda-time:joda-time:2.9.9@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.github.bumptech.glide:disklrucache:4.7.1@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:support-core-ui-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: org.jetbrains:annotations:16.0.1@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: android.arch.lifecycle:extensions-1.1.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.android.support.test.espresso:espresso-core-3.0.2\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.yanzhenjie:loading-1.0.2\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: android.arch.core:common:1.1.1@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:asynclayoutinflater-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:swiperefreshlayout-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: io.reactivex.rxjava2:rxandroid-2.0.2\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: top.zibin:Luban-1.1.3\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: junit:junit:4.12@jar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.hamcrest:hamcrest-core:1.3@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.databinding:baseLibrary:3.1.3@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:cardview-v7-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:viewpager-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.google.dagger:dagger:2.13@jar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.android.support.test.espresso:espresso-idling-resource-3.0.2\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.squareup.okhttp3:okhttp:3.10.0@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:localbroadcastmanager-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:recyclerview-v7-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.google.code.gson:gson:2.8.2@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:support-fragment-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:support-compat-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.timehop.stickyheadersrecyclerview:library-0.4.3\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.github.bumptech.glide:gifdecoder-4.7.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:collections:28.0.0-rc02@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:design-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.hamcrest:hamcrest-integration:1.3@jar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.hamcrest:hamcrest-library:1.3@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.github.bumptech.glide:annotations:4.7.1@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: android.arch.lifecycle:common:1.1.1@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: android.arch.lifecycle:livedata-core-1.1.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.crashlytics.sdk.android:answers-1.4.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.umeng.sdk:analytics:7.5.3@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.google.dagger:dagger-android-support-2.13\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.umeng.sdk:common:1.5.3@jar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.android.support:support-vector-drawable-28.0.0-rc02\" level=\"project\" />\n    <orderEntry type=\"module\" module-name=\"commons\" />\n  </component>\n</module>"
  },
  {
    "path": "advanced/build.gradle",
    "content": "println isAdvancedModuleApp.toBoolean()\napply plugin: \"build-time-tracker\"\n\nif (isAdvancedModuleApp.toBoolean()) {\n    apply plugin: 'com.android.application'\n} else {\n    apply plugin: 'com.android.library'\n}\napply plugin: 'com.getkeepsafe.dexcount'\n\nandroid {\n    compileSdkVersion rootProject.ext.compileSdkVersion\n    defaultConfig {\n        minSdkVersion rootProject.ext.minSdkVersion\n        targetSdkVersion rootProject.ext.targetSdkVersion\n        versionCode 1\n        versionName \"1.0\"\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n        multiDexEnabled true\n        javaCompileOptions {\n            annotationProcessorOptions {\n                arguments = [moduleName: project.getName()]\n            }\n        }\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n    // use data binding\n    dataBinding {\n        enabled = true\n    }\n    // use java 8 language\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n    // use external libs folder\n    sourceSets {\n        main {\n            jniLibs.srcDirs = ['libs']\n            if (isAdvancedModuleApp.toBoolean()) {\n                manifest.srcFile \"src/main/debug/AndroidManifest.xml\"\n            } else {\n                manifest.srcFile \"src/main/AndroidManifest.xml\"\n            }\n        }\n    }\n    // dex count. see https://github.com/KeepSafe/dexcount-gradle-plugin\n    dexcount {\n        format = \"list\"\n        includeClasses = false\n        includeClassCount = false\n        includeFieldCount = true\n        includeTotalMethodCount = false\n        orderByMethodCount = false\n        verbose = false\n        maxTreeDepth = Integer.MAX_VALUE\n        teamCityIntegration = false\n        teamCitySlug = null\n        runOnEachPackage = true\n//        maxMethodCount = 64000\n        enabled = true\n    }\n}\n\ndependencies {\n    implementation fileTree(dir: 'libs', include: ['*.jar'])\n    testImplementation 'junit:junit:4.12'\n    androidTestImplementation 'androidx.test:runner:1.1.1'\n    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'\n    testImplementation 'org.mockito:mockito-inline:2.22.0'\n    androidTestImplementation 'org.mockito:mockito-inline:2.22.0'\n    // router\n    annotationProcessor 'com.alibaba:arouter-compiler:1.1.4'\n    // projects\n    implementation project(':commons')\n}\n"
  },
  {
    "path": "advanced/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "advanced/src/androidTest/java/me/shouheng/advanced/ExampleInstrumentedTest.java",
    "content": "package me.shouheng.advanced;\n\nimport android.content.Context;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport androidx.test.InstrumentationRegistry;\nimport androidx.test.runner.AndroidJUnit4;\n\nimport static androidx.test.espresso.Espresso.onView;\nimport static androidx.test.espresso.action.ViewActions.click;\nimport static androidx.test.espresso.matcher.ViewMatchers.withId;\nimport static org.junit.Assert.assertEquals;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"me.shouheng.advanced.test\", appContext.getPackageName());\n    }\n\n    public void testClick(int id) {\n        onView(withId(id)).perform(click());\n    }\n}\n"
  },
  {
    "path": "advanced/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"me.shouheng.advanced\" >\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\" >\n        <activity android:name=\".MainActivity\"/>\n        <activity android:name=\".remote.RemoteActivity\"\n            android:process=\":remote\"/>\n        <activity android:name=\".remote.Remote2Activity\"\n            android:process=\"remote.sample\"/>\n        <service android:name=\".aidl.NoteService\"\n            android:process=\":remote\"/>\n        <service android:name=\".messenger.MessengerService\"\n            android:process=\":remote\"/>\n        <activity android:name=\".Activity2\"/>\n        <service android:name=\".keepalive.LongLiveService\"/>\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "advanced/src/main/aidl/me/shouheng/advanced/aidl/INoteManager.aidl",
    "content": "package me.shouheng.advanced.aidl;\n\nimport me.shouheng.advanced.aidl.Note;\n\ninterface INoteManager {\n    Note getNote(long id);\n    void addNote(long id, String name);\n}\n"
  },
  {
    "path": "advanced/src/main/aidl/me/shouheng/advanced/aidl/Note.aidl",
    "content": "package me.shouheng.advanced.aidl;\n\nparcelable Note;"
  },
  {
    "path": "advanced/src/main/debug/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"me.shouheng.advanced\" >\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:name=\".ModuleAdvancedApp\"\n        android:theme=\"@style/AppTheme\">\n        <activity android:name=\".MainActivity\" >\n            <intent-filter>\n                <action android:name=\"android.intent.action.VIEW\"/>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n        <activity android:name=\".remote.RemoteActivity\"\n            android:process=\":remote\"/>\n        <activity android:name=\".remote.Remote2Activity\"\n            android:process=\"remote.sample\"/>\n        <service android:name=\".aidl.NoteService\"\n            android:process=\":remote\"/>\n        <service android:name=\".messenger.MessengerService\"\n            android:process=\":remote\"/>\n        <activity android:name=\".Activity2\"/>\n        <service android:name=\".keepalive.LongLiveService\"/>\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "advanced/src/main/java/me/shouheng/advanced/Activity2.java",
    "content": "package me.shouheng.advanced;\n\nimport android.app.Activity;\nimport android.content.Intent;\nimport android.os.Bundle;\n\nimport me.shouheng.advanced.databinding.Activity2Binding;\nimport me.shouheng.commons.view.activity.CommonActivity;\n\n/**\n * Created on 2018/12/26.\n */\npublic class Activity2 extends CommonActivity<Activity2Binding> {\n\n    public static final String EXTRA_KEY_NAME = \"EXTRA\";\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_2;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        getBinding().cfrm.setOnClickListener(v -> {\n            Intent intent = new Intent();\n            intent.putExtra(EXTRA_KEY_NAME, getBinding().et.getText().toString());\n            setResult(Activity.RESULT_OK, intent);\n            finish();\n        });\n    }\n}\n"
  },
  {
    "path": "advanced/src/main/java/me/shouheng/advanced/MainActivity.java",
    "content": "package me.shouheng.advanced;\n\nimport android.content.ComponentName;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.content.ServiceConnection;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.IBinder;\nimport android.os.Message;\nimport android.os.Messenger;\nimport android.os.RemoteException;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.alibaba.android.arouter.launcher.ARouter;\n\nimport androidx.annotation.Nullable;\nimport me.shouheng.advanced.aidl.INoteManager;\nimport me.shouheng.advanced.aidl.Note;\nimport me.shouheng.advanced.aidl.NoteService;\nimport me.shouheng.advanced.callback.ActResultRequest;\nimport me.shouheng.advanced.databinding.ActivityAdvancedBinding;\nimport me.shouheng.advanced.keepalive.LongLiveService;\nimport me.shouheng.advanced.messenger.MessengerService;\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.LogUtils;\nimport me.shouheng.commons.tools.ToastUtils;\nimport me.shouheng.commons.view.activity.CommonActivity;\n\n/**\n * @author shouh\n * @version $Id: MainActivity, v 0.1 2018/10/22 21:36 shouh Exp$\n */\n@Route(path = BaseConstants.ADVANCED_MENU)\npublic class MainActivity extends CommonActivity<ActivityAdvancedBinding> {\n\n    private INoteManager noteManager;\n\n    private ServiceConnection connection = new ServiceConnection() {\n        @Override\n        public void onServiceConnected(ComponentName name, IBinder service) {\n            noteManager = INoteManager.Stub.asInterface(service);\n            try {\n                Note note = noteManager.getNote(100);\n                LogUtils.d(note);\n            } catch (RemoteException e) {\n                e.printStackTrace();\n            }\n        }\n\n        @Override\n        public void onServiceDisconnected(ComponentName name) { }\n    };\n\n    public static final int MSG_REPLAY_ID = 0x0012;\n    public static final String MSG_EXTRA_REPLAY_STRING = \"__extra_replay_string\";\n    private boolean serviceConnected = false;\n    private Messenger boundServiceMessenger = null;\n    private final Messenger receiveMessenger = new Messenger(new ReceiveMessHandler());\n    private ServiceConnection msgConn = new ServiceConnection() {\n        @Override\n        public void onServiceConnected(ComponentName name, IBinder service) {\n            boundServiceMessenger = new Messenger(service);\n            serviceConnected = true;\n        }\n\n        @Override\n        public void onServiceDisconnected(ComponentName name) {\n            serviceConnected = false;\n        }\n    };\n    private static class ReceiveMessHandler extends Handler {\n        @Override\n        public void handleMessage(Message msg) {\n            switch (msg.what) {\n                case MSG_REPLAY_ID:\n                    ToastUtils.makeToast(\"收到返回结果：\"+msg.getData().getString(MSG_EXTRA_REPLAY_STRING));\n                    break;\n            }\n        }\n    }\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_advanced;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        /* 开启远程的活动 */\n        getBinding().btnRemote.setOnClickListener(v ->\n                ARouter.getInstance().build(BaseConstants.ADVANCED_REMOTE)\n                        .withString(BaseConstants.ADVANCED_REMOTE_ARG_CONTENT, \"Simple advanced content\")\n                        .navigation());\n        getBinding().btnRemote2.setOnClickListener(v ->\n                ARouter.getInstance().build(BaseConstants.ADVANCED_REMOTE2)\n                        .withString(BaseConstants.ADVANCED_REMOTE2_ARG_CONTENT, \"Simple advanced content 2\")\n                        .navigation());\n\n        /* 两种获取程序执行结果的效果的对比 */\n        getBinding().btnResult.setOnClickListener(v -> {\n            Intent intent = new Intent(this, Activity2.class);\n            ActResultRequest request = new ActResultRequest(this);\n\n            /* 实际的原理就是通过一个没有背景的 fragment 来发起请求并在其中处理请求并进行回调\n             * 问题：当不保留活动的时候 GG */\n            request.startForResult(intent, 1, (resultCode, data) -> {\n                String result = data.getStringExtra(Activity2.EXTRA_KEY_NAME);\n                ToastUtils.makeToast(result);\n            });\n        });\n        getBinding().btnResult2.setOnClickListener(v -> {\n            /* 正常的启动活动并获取结果的逻辑，即使不保留活动也正常运行 */\n            Intent intent = new Intent(this, Activity2.class);\n            startActivityForResult(intent, 0);\n        });\n\n        /* 跨进程获取笔记信息 */\n        getBinding().btnDisplay.setOnClickListener(v -> {\n            try {\n                Note note = noteManager.getNote(100);\n                ToastUtils.makeToast(note + \"\");\n            } catch (RemoteException e) {\n                e.printStackTrace();\n            }\n        });\n\n        /* 启动前台服务 */\n        getBinding().btnFore.setOnClickListener(v -> {\n            Intent intent = new Intent(this, LongLiveService.class);\n            startService(intent);\n        });\n\n        /* 使用 Messenger 发送消息 */\n        getBinding().btnMessenger.setOnClickListener(v -> {\n            Message message = Message.obtain(null, MessengerService.MSG_SAY_SOMETHING);\n            message.replyTo = receiveMessenger;\n            Bundle bundle = new Bundle();\n            bundle.putString(MessengerService.MSG_EXTRA_COMMAND, \"11111\");\n            message.setData(bundle);\n            try {\n                boundServiceMessenger.send(message);\n            } catch (RemoteException ex) {\n                ex.printStackTrace();\n            }\n        });\n\n        /* 绑定 NoteService */\n//        Intent intent = new Intent(this, NoteService.class);\n//        bindService(intent, connection, Context.BIND_AUTO_CREATE);\n\n        /* 绑定 MessengerService */\n        Intent intent1 = new Intent(this, MessengerService.class);\n        bindService(intent1, msgConn, Context.BIND_AUTO_CREATE);\n    }\n\n    @Override\n    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {\n        super.onActivityResult(requestCode, resultCode, data);\n        switch (requestCode) {\n            case 0:\n                assert data != null;\n                String result = data.getStringExtra(Activity2.EXTRA_KEY_NAME);\n                ToastUtils.makeToast(result);\n                break;\n            default:\n                // do nothing\n        }\n    }\n\n    @Override\n    protected void onDestroy() {\n        super.onDestroy();\n        unbindService(connection);\n        if (serviceConnected) {\n            unbindService(msgConn);\n        }\n    }\n}\n"
  },
  {
    "path": "advanced/src/main/java/me/shouheng/advanced/ModuleAdvancedApp.java",
    "content": "package me.shouheng.advanced;\n\nimport com.alibaba.android.arouter.launcher.ARouter;\n\nimport me.shouheng.commons.BaseApplication;\n\n/**\n * @author shouh\n * @version $Id: ModuleGuokrApp, v 0.1 2018/6/6 22:30 shouh Exp$\n */\npublic class ModuleAdvancedApp extends BaseApplication {\n\n    private static ModuleAdvancedApp application;\n\n    public static ModuleAdvancedApp getContext() {\n        return application;\n    }\n\n    @Override\n    public void onCreate() {\n        super.onCreate();\n        application = this;\n\n        ARouter.init(this);\n    }\n}\n"
  },
  {
    "path": "advanced/src/main/java/me/shouheng/advanced/aidl/Note.java",
    "content": "package me.shouheng.advanced.aidl;\n\nimport android.os.Parcel;\nimport android.os.Parcelable;\n\n/**\n * @author shouh\n * @version $Id: Note, v 0.1 2018/10/22 22:27 shouh Exp$\n */\npublic class Note implements Parcelable {\n\n    public final long id;\n\n    public final String name;\n\n    public Note(long id, String name) {\n        this.id = id;\n        this.name = name;\n    }\n\n    protected Note(Parcel in) {\n        id = in.readLong();\n        name = in.readString();\n    }\n\n    public static final Creator<Note> CREATOR = new Creator<Note>() {\n        @Override\n        public Note createFromParcel(Parcel in) {\n            return new Note(in);\n        }\n\n        @Override\n        public Note[] newArray(int size) {\n            return new Note[size];\n        }\n    };\n\n    @Override\n    public String toString() {\n        return \"Note{\" +\n                \"id=\" + id +\n                \", name='\" + name + '\\'' +\n                '}';\n    }\n\n    @Override\n    public int describeContents() {\n        return 0;\n    }\n\n    @Override\n    public void writeToParcel(Parcel dest, int flags) {\n        dest.writeLong(id);\n        dest.writeString(name);\n    }\n}\n"
  },
  {
    "path": "advanced/src/main/java/me/shouheng/advanced/aidl/NoteService.java",
    "content": "package me.shouheng.advanced.aidl;\n\nimport android.app.Notification;\nimport android.app.PendingIntent;\nimport android.app.Service;\nimport android.content.Intent;\nimport android.os.Binder;\nimport android.os.Handler;\nimport android.os.IBinder;\nimport android.os.Message;\n\nimport androidx.annotation.Nullable;\n\nimport java.util.concurrent.CopyOnWriteArrayList;\nimport java.util.concurrent.TimeUnit;\n\nimport io.reactivex.Observable;\nimport io.reactivex.functions.Consumer;\nimport me.shouheng.advanced.MainActivity;\nimport me.shouheng.advanced.R;\nimport me.shouheng.commons.tools.LogUtils;\n\n/**\n * @author shouh\n * @version $Id: NoteService, v 0.1 2018/10/23 21:20 shouh Exp$\n */\npublic class NoteService extends Service {\n\n    private CopyOnWriteArrayList<Note> notes = new CopyOnWriteArrayList<>();\n\n    private Binder binder = new INoteManager.Stub() {\n        @Override\n        public Note getNote(long id) {\n            return Observable.fromIterable(notes).filter(note -> note.id == id).singleOrError().blockingGet();\n        }\n\n        @Override\n        public void addNote(long id, String name) {\n            notes.add(new Note(id, name));\n        }\n    };\n\n    @Override\n    public void onCreate() {\n        super.onCreate();\n        notes.add(new Note(100, \"Note 100\"));\n        notes.add(new Note(101, \"Note 101\"));\n        LogUtils.d(\"========== onCreate()\");\n\n        Notification notification = new Notification.Builder(getApplicationContext())\n                .setContentTitle(\"Content Title\")\n                .setContentText(\"Content Text\")\n                .setSmallIcon(R.drawable.ic_launcher_foreground)\n                .build();\n        Intent intent = new Intent(this, MainActivity.class);\n        notification.contentIntent = PendingIntent.getActivity(this, 0, intent, 0);\n        startForeground(1, notification);\n    }\n\n    @Nullable\n    @Override\n    public IBinder onBind(Intent intent) {\n        LogUtils.d(\"========== onBind()\");\n        Observable.interval(1, TimeUnit.SECONDS).subscribe(new Consumer<Long>() {\n            @Override\n            public void accept(Long aLong) throws Exception {\n                LogUtils.d(\"========== \" + aLong);\n            }\n        });\n        return binder;\n    }\n\n    @Override\n    public void onRebind(Intent intent) {\n        super.onRebind(intent);\n        LogUtils.d(\"========== onRebind()\");\n    }\n\n    @Override\n    public boolean onUnbind(Intent intent) {\n        LogUtils.d(\"========== onUnbind()\");\n        return super.onUnbind(intent);\n    }\n\n    @Override\n    public void onDestroy() {\n        super.onDestroy();\n        LogUtils.d(\"========== onDestroy()\");\n    }\n}\n"
  },
  {
    "path": "advanced/src/main/java/me/shouheng/advanced/callback/ActResultRequest.java",
    "content": "package me.shouheng.advanced.callback;\n\nimport android.content.Intent;\n\nimport androidx.appcompat.app.AppCompatActivity;\nimport androidx.fragment.app.FragmentManager;\n\n/**\n * Created on 2018/12/26.\n */\npublic class ActResultRequest {\n\n    private OnActResultEventDispatcherFragment fragment;\n\n    /**\n     * new 一个 ActResultRequest 的时候会初始化一个没有背景的 Fragment\n     *\n     * @param activity\n     */\n    public ActResultRequest(AppCompatActivity activity) {\n        fragment = getEventDispatchFragment(activity);\n    }\n\n    private OnActResultEventDispatcherFragment getEventDispatchFragment(AppCompatActivity activity) {\n        final FragmentManager fragmentManager = activity.getSupportFragmentManager();\n\n        OnActResultEventDispatcherFragment fragment = findEventDispatchFragment(fragmentManager);\n        if (fragment == null) {\n            fragment = new OnActResultEventDispatcherFragment();\n            fragmentManager\n                    .beginTransaction()\n                    .add(fragment, OnActResultEventDispatcherFragment.TAG)\n                    .commitAllowingStateLoss();\n            fragmentManager.executePendingTransactions();\n        }\n        return fragment;\n    }\n\n    private OnActResultEventDispatcherFragment findEventDispatchFragment(FragmentManager manager) {\n        return (OnActResultEventDispatcherFragment) manager.findFragmentByTag(OnActResultEventDispatcherFragment.TAG);\n    }\n\n    /**\n     * 当调用 startForResult 的时候，实际上是调用 fragment 的 startForResult 方法\n     *\n     * @param intent\n     * @param requestCode\n     * @param callback\n     */\n    public void startForResult(Intent intent, int requestCode, Callback callback) {\n        fragment.startForResult(intent, requestCode, callback);\n    }\n\n    public interface Callback {\n        void onActivityResult(int resultCode, Intent data);\n    }\n}\n"
  },
  {
    "path": "advanced/src/main/java/me/shouheng/advanced/callback/OnActResultEventDispatcherFragment.java",
    "content": "package me.shouheng.advanced.callback;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.util.SparseArray;\n\nimport androidx.fragment.app.Fragment;\n\n/**\n * Created on 2018/12/26.\n */\npublic class OnActResultEventDispatcherFragment extends Fragment {\n\n    public static final String TAG = \"on_act_result_event_dispatcher\";\n\n    private SparseArray<ActResultRequest.Callback> mCallbacks = new SparseArray<>();\n\n    @Override\n    public void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setRetainInstance(true);\n    }\n\n    /**\n     * 这里的 fragment 调用自己的 startActivityForResult 方法来获取结果\n     *\n     * @param intent\n     * @param requestCode\n     * @param callback\n     */\n    public void startForResult(Intent intent, int requestCode, ActResultRequest.Callback callback) {\n        mCallbacks.put(requestCode, callback);\n        startActivityForResult(intent, requestCode);\n    }\n\n    /**\n     * 当拿到结果之后从列表中找出回调并调用\n     *\n     * @param requestCode\n     * @param resultCode\n     * @param data\n     */\n    @Override\n    public void onActivityResult(int requestCode, int resultCode, Intent data) {\n        super.onActivityResult(requestCode, resultCode, data);\n\n        ActResultRequest.Callback callback = mCallbacks.get(requestCode);\n        mCallbacks.remove(requestCode);\n\n        if (callback != null) {\n            callback.onActivityResult(resultCode, data);\n        }\n    }\n\n}"
  },
  {
    "path": "advanced/src/main/java/me/shouheng/advanced/keepalive/LongLiveService.java",
    "content": "package me.shouheng.advanced.keepalive;\n\nimport android.app.Notification;\nimport android.app.NotificationChannel;\nimport android.app.NotificationManager;\nimport android.app.PendingIntent;\nimport android.app.Service;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.os.IBinder;\n\nimport java.util.concurrent.TimeUnit;\n\nimport androidx.annotation.Nullable;\nimport androidx.core.app.NotificationCompat;\nimport io.reactivex.Observable;\nimport me.shouheng.advanced.MainActivity;\nimport me.shouheng.advanced.R;\nimport me.shouheng.commons.tools.LogUtils;\n\n/**\n * 通过设置为前台服务的形式进行保活\n * 另外还有在 onStartCommand() 中返回 START_STICKY\n *\n * Created on 2018/12/26.\n */\npublic class LongLiveService extends Service {\n\n    @Override\n    public void onCreate() {\n        /* 启动前台服务保活 */\n        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {\n            NotificationManager notificationManager = (NotificationManager)\n                    getSystemService(Context.NOTIFICATION_SERVICE);\n\n            CharSequence name = \"FOREGROUND\";\n            String description = \"\";\n            NotificationChannel channel;\n            int importance = NotificationManager.IMPORTANCE_DEFAULT;\n            channel = new NotificationChannel(\"ChannelId\", name, importance);\n            channel.setDescription(description);\n            notificationManager.createNotificationChannel(channel);\n        }\n\n        Notification notification = new NotificationCompat.Builder(getApplicationContext(), \"ChannelId\")\n                .setContentTitle(\"Content Title 2\")\n                .setContentText(\"Content Text 2\")\n                .setSmallIcon(R.drawable.ic_launcher_foreground)\n                .build();\n        Intent intent = new Intent(this, MainActivity.class);\n        notification.contentIntent = PendingIntent.getActivity(this, 0, intent, 0);\n        startForeground(2, notification);\n\n        /* 每隔 1 秒的时间输出一个日志 */\n        Observable.interval(1, TimeUnit.SECONDS).subscribe(aLong -> LogUtils.d(\"LongLive \" + aLong)).isDisposed();\n    }\n\n    @Override\n    public int onStartCommand(Intent intent, int flags, int startId) {\n        /* 返回 START_STICKY，可以做到在“正在运行的服务”中停止的时候自启 */\n        return START_STICKY;\n    }\n\n    @Nullable\n    @Override\n    public IBinder onBind(Intent intent) {\n        return null;\n    }\n\n    @Override\n    public boolean onUnbind(Intent intent) {\n        return super.onUnbind(intent);\n    }\n\n    @Override\n    public void onRebind(Intent intent) {\n        // do nothing\n    }\n\n    @Override\n    public void onDestroy() {\n        Intent intent = new Intent(this, LongLiveService.class);\n        startService(intent);\n    }\n}\n"
  },
  {
    "path": "advanced/src/main/java/me/shouheng/advanced/messenger/MessengerService.java",
    "content": "package me.shouheng.advanced.messenger;\n\nimport android.app.Service;\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.IBinder;\nimport android.os.Message;\nimport android.os.Messenger;\nimport android.os.RemoteException;\n\nimport java.lang.ref.WeakReference;\n\nimport androidx.annotation.Nullable;\nimport me.shouheng.commons.tools.ToastUtils;\n\nimport static me.shouheng.advanced.MainActivity.MSG_EXTRA_REPLAY_STRING;\nimport static me.shouheng.advanced.MainActivity.MSG_REPLAY_ID;\n\n/**\n * @author WngShhng (shouheng2015@gmail.com)\n * @version $Id: MessengerService, v 0.1 2019/2/16 14:38 shouh Exp$\n */\npublic class MessengerService extends Service {\n\n    public static final int MSG_SAY_SOMETHING = 11;\n\n    public static final String MSG_EXTRA_COMMAND = \"__extra_command\";\n\n    private static class MessengerHandler extends Handler {\n\n        private WeakReference<Service> serviceRef;\n\n        MessengerHandler(Service service) {\n            this.serviceRef = new WeakReference<>(service);\n        }\n\n        @Override\n        public void handleMessage(Message msg) {\n            switch (msg.what) {\n                case MSG_SAY_SOMETHING:\n                    ToastUtils.makeToast(\"远程服务收到消息，内容是：\" + msg.getData().getString(MSG_EXTRA_COMMAND));\n                    // 向客户端返回消息\n                    Messenger client = msg.replyTo;\n                    Message message = Message.obtain(null, MSG_REPLAY_ID);\n                    Bundle bundle = new Bundle();\n                    bundle.putString(MSG_EXTRA_REPLAY_STRING, \"00000\");\n                    message.setData(bundle);\n                    try {\n                        client.send(message);\n                    } catch (RemoteException e) {\n                        e.printStackTrace();\n                    }\n                    break;\n            }\n        }\n    }\n\n    private Messenger messenger = new Messenger(new MessengerHandler(this));\n\n    @Nullable\n    @Override\n    public IBinder onBind(Intent intent) {\n        ToastUtils.makeToast(\"MessengerService bound!\");\n        return messenger.getBinder();\n    }\n}\n"
  },
  {
    "path": "advanced/src/main/java/me/shouheng/advanced/remote/Remote2Activity.java",
    "content": "package me.shouheng.advanced.remote;\n\nimport android.os.Bundle;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n\nimport me.shouheng.advanced.R;\nimport me.shouheng.advanced.databinding.ActivityRemoteBinding;\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.view.activity.CommonActivity;\n\n/**\n * @author shouh\n * @version $Id: Remote2Activity, v 0.1 2018/10/22 22:15 shouh Exp$\n */\n@Route(path = BaseConstants.ADVANCED_REMOTE2)\npublic class Remote2Activity extends CommonActivity<ActivityRemoteBinding> {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_remote;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        String content = getIntent().getStringExtra(BaseConstants.ADVANCED_REMOTE2_ARG_CONTENT);\n        getBinding().tvContent.setText(content);\n    }\n}\n"
  },
  {
    "path": "advanced/src/main/java/me/shouheng/advanced/remote/RemoteActivity.java",
    "content": "package me.shouheng.advanced.remote;\n\nimport android.os.Bundle;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n\nimport me.shouheng.advanced.R;\nimport me.shouheng.advanced.databinding.ActivityRemoteBinding;\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.view.activity.CommonActivity;\n\n/**\n * @author shouh\n * @version $Id: RemoteActivity, v 0.1 2018/10/22 22:03 shouh Exp$\n */\n@Route(path = BaseConstants.ADVANCED_REMOTE)\npublic class RemoteActivity extends CommonActivity<ActivityRemoteBinding> {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_remote;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        String content = getIntent().getStringExtra(BaseConstants.ADVANCED_REMOTE_ARG_CONTENT);\n        getBinding().tvContent.setText(content);\n    }\n}\n"
  },
  {
    "path": "advanced/src/main/res/layout/activity_2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <LinearLayout\n        android:orientation=\"vertical\"\n        android:fitsSystemWindows=\"true\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <androidx.appcompat.widget.AppCompatEditText\n            android:id=\"@+id/et\"\n            android:hint=\"Say something...\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/cfrm\"\n            android:text=\"Confirm\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n    </LinearLayout>\n\n</layout>"
  },
  {
    "path": "advanced/src/main/res/layout/activity_advanced.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout  xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <LinearLayout\n        android:fitsSystemWindows=\"true\"\n        android:orientation=\"vertical\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_remote\"\n            android:text=\"Start Remote Activity\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_remote2\"\n            android:text=\"Start Remote Activity 2\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_result\"\n            android:text=\"Start For Result CALLBACK\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_result2\"\n            android:text=\"Start For Result NORMAL\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_display\"\n            android:text=\"Display NoteManager info\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_fore\"\n            android:text=\"启动前台服务\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_messenger\"\n            android:text=\"使用 Messenger 发送消息\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n    </LinearLayout>\n\n</layout>"
  },
  {
    "path": "advanced/src/main/res/layout/activity_remote.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <LinearLayout\n        android:fitsSystemWindows=\"true\"\n        android:orientation=\"vertical\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <androidx.appcompat.widget.AppCompatTextView\n            android:id=\"@+id/tv_content\"\n            android:padding=\"16dp\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n    </LinearLayout>\n\n</layout>"
  },
  {
    "path": "advanced/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Advanced</string>\n</resources>\n"
  },
  {
    "path": "advanced/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <item name=\"colorPrimary\">@color/colorAccent</item>\n        <item name=\"colorPrimaryDark\">#0068db</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "advanced/src/test/java/me/shouheng/advanced/ExampleUnitTest.java",
    "content": "package me.shouheng.advanced;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "animations/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "animations/build.gradle",
    "content": "println isAnimationsModuleApp.toBoolean()\n\nif (isAnimationsModuleApp.toBoolean()) {\n    apply plugin: 'com.android.application'\n} else {\n    apply plugin: 'com.android.library'\n}\n\nandroid {\n    compileSdkVersion rootProject.ext.compileSdkVersion\n    defaultConfig {\n        minSdkVersion rootProject.ext.minSdkVersion\n        targetSdkVersion rootProject.ext.targetSdkVersion\n        versionCode 1\n        versionName \"1.0\"\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n        javaCompileOptions {\n            annotationProcessorOptions {\n                arguments = [moduleName: project.getName()]\n            }\n        }\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n    // use data binding\n    dataBinding {\n        enabled = true\n    }\n    // use java 8 language\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n    // use external libs folder\n    sourceSets {\n        main {\n            jniLibs.srcDirs = ['libs']\n            if (isAnimationsModuleApp.toBoolean()) {\n                manifest.srcFile \"src/main/debug/AndroidManifest.xml\"\n            } else {\n                manifest.srcFile \"src/main/AndroidManifest.xml\"\n            }\n        }\n    }\n}\n\ndependencies {\n    implementation fileTree(dir: 'libs', include: ['*.jar'])\n    testImplementation 'junit:junit:4.12'\n    androidTestImplementation 'androidx.test:runner:1.1.0'\n    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'\n    // router\n    annotationProcessor 'com.alibaba:arouter-compiler:1.1.4'\n    // CircularReveal\n    implementation ('com.github.ozodrukh:CircularReveal:2.0.1@aar') {\n        transitive = true\n    }\n    // target view\n    implementation 'com.getkeepsafe.taptargetview:taptargetview:1.12.0'\n    // ripple\n    implementation 'com.balysv:material-ripple:1.0.2'\n    // projects\n    implementation project(':commons')\n}\n"
  },
  {
    "path": "animations/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "animations/src/androidTest/java/me/shouheng/animations/ExampleInstrumentedTest.java",
    "content": "package me.shouheng.animations;\n\nimport android.content.Context;\nimport androidx.test.InstrumentationRegistry;\nimport androidx.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"me.shouheng.animations\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "animations/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"me.shouheng.animations\">\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\" >\n        <activity android:name=\".MainActivity\"/>\n        <activity android:name=\".reveal.CircleRevealActivity\"/>\n        <activity android:name=\".DrawableActivity\"/>\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "animations/src/main/debug/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"me.shouheng.animations\">\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:name=\".ModuleAnimationsApp\"\n        android:theme=\"@style/AppTheme\">\n        <activity android:name=\".MainActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n        <activity android:name=\".reveal.CircleRevealActivity\"/>\n        <activity android:name=\".DrawableActivity\"/>\n    </application>\n\n</manifest>"
  },
  {
    "path": "animations/src/main/java/me/shouheng/animations/DrawableActivity.java",
    "content": "package me.shouheng.animations;\n\nimport android.os.Bundle;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n\nimport me.shouheng.animations.databinding.ActivityDrawableBinding;\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.view.activity.CommonActivity;\n\n/**\n * Created by WngShhng on 2018/10/17.\n */\n@Route(path = BaseConstants.ANIMATIONS_DRAWABLE)\npublic class DrawableActivity extends CommonActivity<ActivityDrawableBinding> {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_drawable;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n\n    }\n}\n"
  },
  {
    "path": "animations/src/main/java/me/shouheng/animations/MainActivity.java",
    "content": "package me.shouheng.animations;\n\nimport android.graphics.Color;\nimport android.graphics.Rect;\nimport android.os.Bundle;\nimport android.view.Gravity;\nimport android.widget.ImageView;\nimport android.widget.LinearLayout;\nimport android.widget.TextView;\nimport android.widget.Toast;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.alibaba.android.arouter.launcher.ARouter;\nimport com.balysv.materialripple.MaterialRippleLayout;\nimport com.getkeepsafe.taptargetview.TapTarget;\nimport com.getkeepsafe.taptargetview.TapTargetSequence;\n\nimport me.shouheng.animations.databinding.ActivityAnimBinding;\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.PalmUtils;\nimport me.shouheng.commons.tools.ToastUtils;\nimport me.shouheng.commons.view.activity.CommonActivity;\n\n@Route(path = BaseConstants.ANIMATIONS_MENU)\npublic class MainActivity extends CommonActivity<ActivityAnimBinding> {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_anim;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        getBinding().btnReveal.setOnClickListener(v -> ARouter.getInstance().build(BaseConstants.ANIMATIONS_CIRCLE_REVEAL).navigation());\n\n        getBinding().btnToast.setOnClickListener(v -> showToastWithIcon());\n        getBinding().tvDrawable.setOnClickListener(v -> ARouter.getInstance().build(BaseConstants.ANIMATIONS_DRAWABLE).navigation());\n\n        configMaterialRipple();\n\n        configTargetView();\n    }\n\n    private void showToastWithIcon() {\n        Toast toast = new Toast(this);\n        toast.setDuration(Toast.LENGTH_LONG);\n        LinearLayout ly = new LinearLayout(MainActivity.this);\n        ly.setGravity(Gravity.CENTER_VERTICAL);\n        ImageView iv = new ImageView(MainActivity.this);\n        iv.setImageResource(R.mipmap.ic_launcher);\n        TextView tv = new TextView(MainActivity.this);\n        tv.setText(\"Test toast message\");\n        ly.addView(tv);\n        ly.addView(iv);\n        toast.setView(ly);\n        toast.show();\n    }\n\n    private void configMaterialRipple() {\n        MaterialRippleLayout.on(getBinding().tvRipple)\n                .rippleAlpha(0.2f)\n                .rippleHover(true)\n                .rippleColor(Color.BLUE)\n                .create();\n        MaterialRippleLayout.on(getBinding().tvRipple2)\n                .rippleColor(Color.parseColor(\"#FF0000\"))\n                .rippleAlpha(0.2f)\n                .rippleHover(true)\n                .create();\n        getBinding().tvRipple.setOnClickListener(v -> ToastUtils.makeToast(\"Ripple1\"));\n        getBinding().tvRipple2.setOnClickListener(v -> ToastUtils.makeToast(\"Ripple2\"));\n    }\n\n    private void configTargetView() {\n        Rect rect = new Rect(100, 100, 100, 100);\n        new TapTargetSequence(this)\n                .targets(\n                        TapTarget.forView(getBinding().btnReveal, \"Gonna\"),\n                        TapTarget.forView(getBinding().btnToast, \"You\", \"Up\")\n                                .dimColorInt(Color.RED)\n                                .outerCircleColorInt(Color.GREEN)\n                                .targetCircleColorInt(Color.BLUE)\n                                .textColorInt(Color.WHITE),\n                        TapTarget.forBounds(rect, \"Down\", \":^)\")\n                                .cancelable(false)\n                                .icon(PalmUtils.getDrawableCompact(R.drawable.ic_account_circle_black_24dp)))\n                .listener(new TapTargetSequence.Listener() {\n                    @Override\n                    public void onSequenceFinish() {\n                        ToastUtils.makeToast(\"onSequenceFinish\");\n                    }\n\n                    @Override\n                    public void onSequenceStep(TapTarget lastTarget, boolean targetClicked) {\n                        ToastUtils.makeToast(\"onSequenceStep\");\n                    }\n\n                    @Override\n                    public void onSequenceCanceled(TapTarget lastTarget) {\n                        ToastUtils.makeToast(\"onSequenceCanceled\");\n                    }\n                }).start();\n    }\n}\n"
  },
  {
    "path": "animations/src/main/java/me/shouheng/animations/ModuleAnimationsApp.java",
    "content": "package me.shouheng.animations;\n\nimport com.alibaba.android.arouter.launcher.ARouter;\n\nimport me.shouheng.commons.BaseApplication;\n\n/**\n * @author shouh\n * @version $Id: ModuleGuokrApp, v 0.1 2018/6/6 22:30 shouh Exp$\n */\npublic class ModuleAnimationsApp extends BaseApplication {\n\n    private static ModuleAnimationsApp application;\n\n    public static ModuleAnimationsApp getContext() {\n        return application;\n    }\n\n    @Override\n    public void onCreate() {\n        super.onCreate();\n        application = this;\n\n        ARouter.init(this);\n    }\n}\n"
  },
  {
    "path": "animations/src/main/java/me/shouheng/animations/reveal/CircleRevealActivity.java",
    "content": "package me.shouheng.animations.reveal;\n\nimport android.animation.Animator;\nimport android.os.Bundle;\nimport android.view.animation.AccelerateDecelerateInterpolator;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n\nimport io.codetail.animation.ViewAnimationUtils;\nimport me.shouheng.animations.R;\nimport me.shouheng.animations.databinding.ActivityCircleRevealBinding;\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.view.activity.CommonActivity;\n\n@Route(path = BaseConstants.ANIMATIONS_CIRCLE_REVEAL)\npublic class CircleRevealActivity extends CommonActivity<ActivityCircleRevealBinding> {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_circle_reveal;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        getBinding().btn1.setOnClickListener(v -> animate());\n    }\n\n    private void animate() {\n        int cx = (getBinding().vTop.getLeft() + getBinding().vTop.getRight()) / 2;\n        int cy = (getBinding().vTop.getTop() + getBinding().vTop.getBottom()) / 2;\n\n        // get the final radius for the clipping circle\n        int dx = Math.max(cx, getBinding().vTop.getWidth() - cx);\n        int dy = Math.max(cy, getBinding().vTop.getHeight() - cy);\n        float finalRadius = (float) Math.hypot(dx, dy);\n\n        // Android native animator\n        Animator animator = ViewAnimationUtils.createCircularReveal(getBinding().vTop, cx, cy, 0, finalRadius);\n        animator.setInterpolator(new AccelerateDecelerateInterpolator());\n        animator.setDuration(1500);\n        animator.start();\n    }\n}\n"
  },
  {
    "path": "animations/src/main/res/drawable/drawable_bitmap.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<bitmap android:src=\"@drawable/ic_launcher\"\n    android:filter=\"true\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n</bitmap>"
  },
  {
    "path": "animations/src/main/res/drawable/drawable_bitmap_no_filter.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<bitmap android:src=\"@drawable/ic_launcher\"\n    android:tileMode=\"mirror\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n</bitmap>"
  },
  {
    "path": "animations/src/main/res/drawable/drawable_layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n\n\n</layer-list>"
  },
  {
    "path": "animations/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillColor=\"#26A69A\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n"
  },
  {
    "path": "animations/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillType=\"evenOdd\"\n        android:pathData=\"M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"78.5885\"\n                android:endY=\"90.9159\"\n                android:startX=\"48.7653\"\n                android:startY=\"61.0927\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        android:pathData=\"M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\" />\n</vector>\n"
  },
  {
    "path": "animations/src/main/res/layout/activity_anim.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    tools:context=\".MainActivity\">\n\n    <LinearLayout\n        android:fitsSystemWindows=\"true\"\n        android:orientation=\"vertical\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_reveal\"\n            android:text=\"Circle Reveal Demo\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_toast\"\n            android:text=\"Toast with icon\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatTextView\n            android:id=\"@+id/tv_ripple\"\n            android:text=\"Ripple Test\"\n            android:textSize=\"32sp\"\n            android:gravity=\"center\"\n            android:textColor=\"@android:color/black\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatTextView\n            android:id=\"@+id/tv_ripple2\"\n            android:text=\"Ripple Test 2\"\n            android:textSize=\"32sp\"\n            android:gravity=\"center\"\n            android:textColor=\"@android:color/black\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/tv_drawable\"\n            android:text=\"Drawable Activity\"\n            android:textSize=\"32sp\"\n            android:gravity=\"center\"\n            android:textColor=\"@android:color/black\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n    </LinearLayout>\n\n</layout>"
  },
  {
    "path": "animations/src/main/res/layout/activity_circle_reveal.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    tools:context=\".reveal.CircleRevealActivity\">\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <LinearLayout\n            android:orientation=\"vertical\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\">\n\n            <io.codetail.widget.RevealFrameLayout\n                android:layout_weight=\"1\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"0dp\">\n\n                <View android:id=\"@+id/v_top\"\n                    android:background=\"@android:color/holo_green_light\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"match_parent\"/>\n\n            </io.codetail.widget.RevealFrameLayout>\n\n            <io.codetail.widget.RevealLinearLayout\n                android:layout_weight=\"1\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"0dp\">\n\n                <View android:id=\"@+id/v_bottom\"\n                    android:background=\"@android:color/holo_red_light\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"match_parent\"/>\n\n            </io.codetail.widget.RevealLinearLayout>\n\n        </LinearLayout>\n\n        <LinearLayout\n            android:orientation=\"horizontal\"\n            android:layout_centerVertical=\"true\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\">\n\n            <androidx.appcompat.widget.AppCompatButton\n                android:id=\"@+id/btn1\"\n                android:text=\"BUTTON1\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"60dp\" />\n\n        </LinearLayout>\n\n    </RelativeLayout>\n\n</layout>"
  },
  {
    "path": "animations/src/main/res/layout/activity_drawable.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <androidx.core.widget.NestedScrollView\n        android:fitsSystemWindows=\"true\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\">\n\n        <LinearLayout\n            android:orientation=\"vertical\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\">\n\n            <TextView\n                android:text=\"BitmapDrawable\"\n                android:layout_margin=\"10dp\"\n                android:layout_gravity=\"center\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\" />\n\n            <HorizontalScrollView\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"150dp\">\n\n                <LinearLayout\n                    android:orientation=\"horizontal\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"match_parent\">\n\n                    <View\n                        android:background=\"@drawable/drawable_bitmap\"\n                        android:layout_width=\"150dp\"\n                        android:layout_height=\"150dp\"/>\n\n                    <View\n                        android:background=\"@drawable/drawable_bitmap_no_filter\"\n                        android:layout_width=\"150dp\"\n                        android:layout_height=\"150dp\"/>\n\n                </LinearLayout>\n\n            </HorizontalScrollView>\n\n            <TextView\n                android:text=\"ShapeDrawable\"\n                android:layout_margin=\"10dp\"\n                android:layout_gravity=\"center\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\" />\n\n            <TextView\n                android:textSize=\"12sp\"\n                android:text=\"参考：https://github.com/duanhong169/GradientDrawableTuner\"\n                android:layout_gravity=\"center\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\" />\n\n        </LinearLayout>\n\n    </androidx.core.widget.NestedScrollView>\n\n</layout>"
  },
  {
    "path": "animations/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "animations/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "animations/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">animations</string>\n</resources>\n"
  },
  {
    "path": "animations/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <item name=\"colorPrimary\">@color/colorAccent</item>\n        <item name=\"colorPrimaryDark\">#0068db</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "animations/src/test/java/me/shouheng/animations/ExampleUnitTest.java",
    "content": "package me.shouheng.animations;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "client/.gitignore",
    "content": "# Built application files\n*.apk\n*.ap_\n\n# Files for the ART/Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbin/\ngen/\nout/\n\n# Gradle files\n.gradle/\nbuild/\n.idea\n\n# Local configuration file (sdk path, etc)\nlocal.properties\n\n# Proguard folder generated by Eclipse\nproguard/\n\n# Log Files\n*.log\n\n# Android Studio Navigation editor temp files\n.navigation/\n\n# Android Studio captures folder\ncaptures/\n\n# IntelliJ\n*.iml\n.idea/workspace.xml\n.idea/tasks.xml\n.idea/gradle.xml\n.idea/dictionaries\n.idea/libraries\n\n# Keystore files\n# Uncomment the following line if you do not want to check your keystore files in.\n#*.jks\n\n# External native build folder generated in Android Studio 2.2 and later\n.externalNativeBuild\n\n# Google Services (e.g. APIs or Firebase)\ngoogle-services.json\n\n# Freeline\nfreeline.py\nfreeline/\nfreeline_project_description.json\n"
  },
  {
    "path": "client/app/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "client/app/build.gradle",
    "content": "apply plugin: 'com.android.application'\napply plugin: 'io.fabric'\napply plugin: 'walle'\napply plugin: 'AndResGuard'\napply plugin: 'com.getkeepsafe.dexcount'\n\nandroid {\n    compileSdkVersion rootProject.ext.compileSdkVersion\n    defaultConfig {\n        applicationId \"me.shouheng.references\"\n        minSdkVersion rootProject.ext.minSdkVersion\n        targetSdkVersion rootProject.ext.targetSdkVersion\n        versionCode 1\n        versionName \"1.0\"\n        // enable multi dex\n        multiDexEnabled true\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n        javaCompileOptions {\n            annotationProcessorOptions {\n                arguments = [ moduleName : project.getName() ]\n            }\n        }\n        manifestPlaceholders = [UMENG_CHANNEL_VALUE: \"umeng\"]\n        ndk {\n            // 只保留 armeabi 和 armeabi-v7a 架构的 so 库，推送中有 so 库，容易导致 UnsatisfiedLinkError\n            abiFilters 'armeabi', 'armeabi-v7a'\n        }\n    }\n    signingConfigs {\n        release {\n            keyAlias 'key0'\n            storeFile file('../palm.jks')\n            storePassword '123456'\n            keyPassword '123456'\n        }\n        debug { }\n    }\n    buildTypes {\n        release {\n            signingConfig signingConfigs.release\n            minifyEnabled false // minify\n            shrinkResources false // enable shrink resources\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n        // config released apk name\n        applicationVariants.all { variant ->\n            variant.outputs.all { output ->\n                outputFileName = defaultConfig.applicationId + \"-\" + variant.baseName + \"-\" + defaultConfig.versionName + \"-\" + defaultConfig.versionCode + \".apk\"\n            }\n        }\n    }\n    productFlavors.all {\n        flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]\n    }\n    // config release types\n    flavorDimensions \"default\"\n    productFlavors {\n        alpha {\n            dimension \"default\"\n        }\n        beta {\n            dimension \"default\"\n        }\n        prod {\n            dimension \"default\"\n        }\n    }\n    // use data binding\n    dataBinding {\n        enabled = true\n    }\n    // use java 8 language\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n    // use external libs folder\n    sourceSets {\n        main {\n            jniLibs.srcDirs = ['libs']\n        }\n    }\n    dexOptions {\n        jumboMode = true\n    }\n    // walle\n    walle {\n        apkOutputFolder = new File(\"${project.buildDir}/outputs/channels\")\n        apkFileNameFormat = '${appName}-${packageName}-${channel}-${buildType}-v${versionName}-${versionCode}-${buildTime}.apk'\n        channelFile = new File(\"${project.getProjectDir()}/channel\")\n    }\n    // andResGuard\n    andResGuard {\n        mappingFile = null\n        use7zip = true\n        useSign = true\n        keepRoot = false\n\n        whiteList = [\n                // for fabric\n                \"R.string.com.crashlytics.*\",\n                // for google-services\n                \"R.string.google_app_id\",\n                \"R.string.gcm_defaultSenderId\",\n                \"R.string.default_web_client_id\",\n                \"R.string.ga_trackingId\",\n                \"R.string.firebase_database_url\",\n                \"R.string.google_api_key\",\n                \"R.string.google_crash_reporting_api_key\"\n        ]\n        compressFilePattern = [\n                \"*.png\",\n                \"*.jpg\",\n                \"*.jpeg\",\n                \"*.gif\",\n        ]\n        sevenzip {\n            artifact = 'com.tencent.mm:SevenZip:1.2.13'\n        }\n    }\n    // dex count\n    dexcount {\n        format = \"list\"\n        includeClasses = false\n        includeClassCount = false\n        includeFieldCount = true\n        includeTotalMethodCount = false\n        orderByMethodCount = false\n        verbose = false\n        maxTreeDepth = Integer.MAX_VALUE\n        teamCityIntegration = false\n        teamCitySlug = null\n        runOnEachPackage = true\n//        maxMethodCount = 64000\n        enabled = true\n    }\n}\n\ndependencies {\n    implementation fileTree(include: ['*.jar'], dir: 'libs')\n    testImplementation 'junit:junit:4.12'\n    androidTestImplementation 'androidx.test:runner:1.1.0'\n    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'\n    // app intro\n    implementation 'com.github.paolorotolo:appintro:1.3.0'\n    // material drawer\n    implementation \"com.mikepenz:materialdrawer:6.1.1\"\n    // awesome fonts and icons\n    implementation 'com.mikepenz:google-material-typeface:3.0.1.2.original@aar'\n    implementation 'com.mikepenz:fontawesome-typeface:5.0.13.0@aar'\n    // router\n    annotationProcessor 'com.alibaba:arouter-compiler:1.1.4'\n    // projects\n    if (!isGuokrModuleApp.toBoolean()) {\n        implementation project(':guokr')\n    }\n    if (!isLiveModuleApp.toBoolean()) {\n        implementation project(':live')\n    }\n    if (!isLayoutModuleApp.toBoolean()) {\n        implementation project(':layout')\n    }\n    if (!isLibraryModuleApp.toBoolean()) {\n        implementation project(':libraries')\n    }\n    if (!isEyepetizerModuleApp.toBoolean()) {\n        implementation project(':eyepetizer')\n    }\n    if (!isAdvancedModuleApp.toBoolean()) {\n        implementation project(':advanced')\n    }\n    if (!isAnimationsModuleApp.toBoolean()) {\n        implementation project(':animations')\n    }\n    implementation project(':commons')\n}\n"
  },
  {
    "path": "client/app/channel",
    "content": "meituan # 美团\nsamsungapps #三星\nhiapk\nanzhi\nxiaomi # 小米\n91com\ngfan\nappchina\nnduoa\n3gcn\nmumayi\n10086com\nwostore\n189store\nlenovomm\nhicloud\nmeizu\nwandou\n# Google Play\n# googleplay\n# 百度\nbaidu\n#\n# 360\n360cn\n#\n# 应用宝\nmyapp"
  },
  {
    "path": "client/app/fabric.properties",
    "content": "#Contains API Secret used to validate your application. Commit to internal source control; avoid making secret public.\n#Wed Jun 06 19:20:45 CST 2018\napiSecret=e4664a037aa796ecf2f8c00b5160724ef5056a17cd29ee650f42b1bc0bc067e6\n"
  },
  {
    "path": "client/app/gradle/wrapper/gradle-wrapper.properties",
    "content": "#Wed Jun 06 19:41:09 CST 2018\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-4.4-all.zip\n"
  },
  {
    "path": "client/app/gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "client/app/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto init\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto init\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:init\n@rem Get command-line arguments, handling Windows variants\n\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\n\n:win9xME_args\n@rem Slurp the command line arguments.\nset CMD_LINE_ARGS=\nset _SKIP=2\n\n:win9xME_args_slurp\nif \"x%~1\" == \"x\" goto execute\n\nset CMD_LINE_ARGS=%*\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "client/app/proguard-rules.pro",
    "content": "#指定压缩级别\n-optimizationpasses 5\n#不跳过非公共的库的类成员\n-dontskipnonpubliclibraryclassmembers\n-dontskipnonpubliclibraryclasses\n#混淆时采用的算法\n-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*\n#把混淆类中的方法名也混淆了\n-useuniqueclassmembernames\n#优化时允许访问并修改有修饰符的类和类的成员\n-allowaccessmodification\n#将文件来源重命名为“SourceFile”字符串\n-renamesourcefileattribute SourceFile\n#保留行号\n-keepattributes SourceFile,LineNumberTable\n# 是否使用大小写混合\n-dontusemixedcaseclassnames\n#混淆时是否记录日志\n-verbose\n#忽略警告，避免打包时某些警告出现\n-ignorewarnings\n#预校验\n-dontpreverify\n#保护注解\n-keepattributes *Annotation*\n#保护JS回调接口\n-keepattributes *JavascriptInterface*\n#保留JavascriptInterface中的方法\n-keepclassmembers class * {\n    @android.webkit.JavascriptInterface <methods>;\n}\n\n#记录生成的日志数据,gradle build时在本项目根目录输出\n#apk 包内所有 class 的内部结构\n-dump class_files.txt\n#未混淆的类和成员\n-printseeds seeds.txt\n#列出从 apk 中删除的代码\n-printusage unused.txt\n#混淆前后的映射\n-printmapping mapping.txt\n\n#保持所有实现 Serializable 接口的类成员\n-keepclassmembers class * implements java.io.Serializable {\n    static final long serialVersionUID;\n    private static final java.io.ObjectStreamField[] serialPersistentFields;\n    private void writeObject(java.io.ObjectOutputStream);\n    private void readObject(java.io.ObjectInputStream);\n    java.lang.Object writeReplace();\n    java.lang.Object readResolve();\n}\n\n# 保持 Parcelable 不被混淆\n-keep class * implements android.os.Parcelable {\n public static final android.os.Parcelable$Creator *;\n}\n\n# 保持枚举 enum 类不被混淆\n-keepclassmembers enum * {\n public static **[] values();\n public static ** valueOf(java.lang.String);\n}\n\n#Fragment不需要在AndroidManifest.xml中注册，需要额外保护下\n-keep public class * extends android.support.v4.app.Fragment\n-keep public class * extends android.app.Fragment\n\n#Social Style Date and Time Formatting for Java\n-keep class org.ocpsoft.prettytime.i18n.**\n\n#如果有引用v4、v7包可以添加下面这行\n-keep public class * extends android.support.*\n\n#解决ActionBar上面的搜索按钮的空指针问题\n-keep class android.support.v7.widget.SearchView { *; }\n\n#过滤泛型\n-keepattributes Signature\n\n# 保持测试相关的代码\n-dontnote junit.framework.**\n-dontnote junit.runner.**\n-dontwarn android.test.**\n-dontwarn android.support.test.**\n-dontwarn org.junit.**\n\n# proguard rules for rx-java\n-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {\n    long producerIndex;\n    long consumerIndex;\n}\n-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {\n    rx.internal.util.atomic.LinkedQueueNode producerNode;\n}\n-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {\n    rx.internal.util.atomic.LinkedQueueNode consumerNode;\n}\n-dontwarn sun.misc.Unsafe\n\n# Umeng 混淆配置\n-keep class com.umeng.** {*;}\n-keepclassmembers class * {\n   public <init> (org.json.JSONObject);\n}\n\n# Retrofit 混淆配置\n-dontnote retrofit2.Platform\n-dontnote retrofit2.Platform$IOS$MainThreadExecutor\n-dontwarn retrofit2.Platform$Java8\n-keepattributes Signature\n-keepattributes Exceptions\n# okhttp 混淆配置\n-dontwarn okio.**\n# Gson 混淆配置\n# TODO 自定义数据模型的bean目录，如果使用了 Retrofit，必须增加该配置\n\n# SwipeRecyclerView\n-keepclasseswithmembers class android.support.v7.widget.RecyclerView$ViewHolder {\n   public final View *;\n}\n-dontwarn com.yanzhenjie.recyclerview.swipe.**\n-keep class com.yanzhenjie.recyclerview.swipe.** {*;}\n\n# 弹出菜单不混淆，需要反射调用其中的字段\n-keep class android.support.v7.widget.PopupMenu { *; }\n\n# Glide\n-keep public class * implements com.bumptech.glide.module.GlideModule\n-keep public class * extends com.bumptech.glide.module.AppGlideModule\n-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {\n  **[] $VALUES;\n  public *;\n}\n\n# sensor\n-dontwarn com.sensorsdata.analytics.android.**\n-keep class com.sensorsdata.analytics.android.** {\n  *;\n}\n-keep class **.R$* {\n  <fields>;\n}\n-keepnames class * implements android.view.View$OnClickListener\n-keep public class * extends android.content.ContentProvider\n-keepnames class * extends android.view.View\n\n-keep class * extends android.app.Fragment {\n public void setUserVisibleHint(boolean);\n public void onHiddenChanged(boolean);\n public void onResume();\n public void onPause();\n}\n-keep class android.support.v4.app.Fragment {\n public void setUserVisibleHint(boolean);\n public void onHiddenChanged(boolean);\n public void onResume();\n public void onPause();\n}\n-keep class * extends android.support.v4.app.Fragment {\n public void setUserVisibleHint(boolean);\n public void onHiddenChanged(boolean);\n public void onResume();\n public void onPause();\n}\n# DataBinding\n-dontwarn android.databinding.**\n-keep class android.databinding.** { *; }\n# TODO 保持 databinding 目录\n# MultiDex\n-keep class com.sensorsdata.analytics.android.** { *; }\n"
  },
  {
    "path": "client/app/src/androidTest/java/me/shouheng/references/ExampleInstrumentedTest.java",
    "content": "package me.shouheng.references;\n\nimport android.content.Context;\nimport androidx.test.InstrumentationRegistry;\nimport androidx.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"me.shouheng.references\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "client/app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"me.shouheng.references\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />\n    <uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\" />\n    <uses-permission android:name=\"android.permission.READ_PHONE_STATE\" />\n    <uses-permission android:name=\"android.permission.WAKE_LOCK\" />\n\n    <application\n        android:name=\".MyApplication\"\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\">\n\n        <activity android:name=\".view.main.MainActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.VIEW\"/>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n            <meta-data android:name=\"android.app.shortcuts\"\n                android:resource=\"@xml/shortcuts\" />\n        </activity>\n\n        <activity android:name=\".view.intro.AppIntroActivity\" />\n\n        <!-- uemng -->\n        <meta-data android:value=\"5b62ef2df43e4841b70003cb\" android:name=\"UMENG_APPKEY\"/>\n        <meta-data android:value=\"${UMENG_CHANNEL_VALUE}\" android:name=\"UMENG_CHANNEL\"/>\n\n        <meta-data\n            android:name=\"io.fabric.ApiKey\"\n            android:value=\"aa14224ea2102fef301d211dac552635f37b1f9e\" />\n\n        <provider\n            android:name=\"androidx.core.content.FileProvider\"\n            android:authorities=\"me.shouheng.references.provider\"\n            android:exported=\"false\"\n            android:grantUriPermissions=\"true\">\n            <meta-data\n                android:name=\"android.support.FILE_PROVIDER_PATHS\"\n                android:resource=\"@xml/provider_paths\" />\n        </provider>\n\n    </application>\n\n</manifest>"
  },
  {
    "path": "client/app/src/main/assets/guokr.articleInline.js",
    "content": "(function(){define(\"ga\",{setGa:function(){(function(e,t,n,r,i,s,o){e.GoogleAnalyticsObject=i,e[i]=e[i]||function(){(e[i].q=e[i].q||[]).push(arguments)},e[i].l=1*new Date,s=t.createElement(n),o=t.getElementsByTagName(n)[0],s.async=1,s.src=r,o.parentNode.insertBefore(s,o)})(window,document,\"script\",\"//www.google-analytics.com/analytics.js\",\"ga\"),ga(\"create\",\"UA-19521615-1\",\"guokr.com\"),ga(\"send\",\"pageview\")}}),define(\"tmpl\",[],function(){function e(e){return String(e).replace(/&/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/\"/g,\"&quot;\")}var t={entities:e};return function(n,r){/\\W/.test(n)||(n=document.getElementById(n).innerHTML);var i=new Function(\"funcs, obj\",\"var p=[],print=function(){p.push.apply(p,arguments);};with(funcs){with(obj){p.push('\"+n.replace(/[\\r\\t\\n]/g,\" \").split(\"<%\").join(\"\t\").replace(/((^|%>)[^\\t]*)'/g,\"$1\\r\").replace(/\\t=(.*?)%>/g,\"',entities($1),'\").replace(/\\t:=(.*?)%>/g,\"',$1,'\").split(\"\t\").join(\"');\").split(\"%>\").join(\"p.push('\").split(\"\\r\").join(\"\\\\'\")+\"');}}return p.join('');\");return r?i(t,r):function(e){return i(t,e)}}}),require([\"ga\",\"tmpl\"],function(e,t){function n(){var e;if(typeof GuokrBridge==\"undefined\")return;e=JSON.parse(GuokrBridge.getRecommendArticles());if(e&&e.length){var n=document.getElementById(\"relaTmpl\").innerHTML,r=t(n,{articles:e});document.getElementById(\"relaListWrap\").innerHTML=r}}(function(e){e.fn.scrollLoading=function(t){var n={attr:\"data-src\"},r=e.extend({},n,t||{});r.cache=[],e(this).each(function(){var t=this.nodeName.toLowerCase(),n=e(this).attr(r.attr);if(!n)return;var i={obj:e(this),tag:t,url:n};r.cache.push(i)});var i=function(){var t=e(window).scrollTop(),n=t+e(window).height();return e.each(r.cache,function(e,r){var i=r.obj,s=r.tag,o=r.url;if(i){post=i.position().top,posb=post+i.height();if(post>t&&post<n||posb>t&&posb<n)s===\"img\"?i.attr(\"src\",o):i.load(o),r.obj=null}}),!1};i(),e(window).bind(\"scroll\",i)}})(jQuery),$(\"#articleContent img\").scrollLoading(),$(\"#articleContent img\").each(function(){var e=$(this),t=e.attr(\"width\"),n=e.attr(\"height\");e.load(function(){e.removeClass(\"load\")}),t&&n&&document.body.clientWidth<768&&(e.width(\"100%\"),n=n/t*e.width(),e.height(n)),e.addClass(\"load\").css(\"opacity\",1)}),e.setGa(),$(\"#relaListWrap\").delegate(\"a[data-id]\",\"click\",function(e){e.preventDefault();var t=$(this),n=t.data(\"id\");typeof GuokrBridge!=\"undefined\"&&GuokrBridge.onRecommendArticleClick(n)}),window.renderRela=n,window.openNightMode=function(){$(\"#contentMain\").addClass(\"night-mode\")},window.closeNightMode=function(){$(\"#contentMain\").removeClass(\"night-mode\")},document.body.addEventListener(\"touchstart\",function(){})}),define(\"articleInline\",function(){})})();"
  },
  {
    "path": "client/app/src/main/assets/guokr.base.js",
    "content": "!function(a,b){function c(a){var b=a.length,c=fa.type(a);return fa.isWindow(a)?!1:1===a.nodeType&&b?!0:\"array\"===c||\"function\"!==c&&(0===b||\"number\"==typeof b&&b>0&&b-1 in a)}function d(a){var b=oa[a]={};return fa.each(a.match(ha)||[],function(a,c){b[c]=!0}),b}function e(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=fa.expando+Math.random()}function f(a,c,d){var e;if(d===b&&1===a.nodeType)if(e=\"data-\"+c.replace(sa,\"-$1\").toLowerCase(),d=a.getAttribute(e),\"string\"==typeof d){try{d=\"true\"===d?!0:\"false\"===d?!1:\"null\"===d?null:+d+\"\"===d?+d:ra.test(d)?JSON.parse(d):d}catch(f){}pa.set(a,c,d)}else d=b;return d}function g(){return!0}function h(){return!1}function i(){try{return T.activeElement}catch(a){}}function j(a,b){for(;(a=a[b])&&1!==a.nodeType;);return a}function k(a,b,c){if(fa.isFunction(b))return fa.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return fa.grep(a,function(a){return a===b!==c});if(\"string\"==typeof b){if(Ca.test(b))return fa.filter(b,a,c);b=fa.filter(b,a)}return fa.grep(a,function(a){return ba.call(b,a)>=0!==c})}function l(a,b){return fa.nodeName(a,\"table\")&&fa.nodeName(1===b.nodeType?b:b.firstChild,\"tr\")?a.getElementsByTagName(\"tbody\")[0]||a.appendChild(a.ownerDocument.createElement(\"tbody\")):a}function m(a){return a.type=(null!==a.getAttribute(\"type\"))+\"/\"+a.type,a}function n(a){var b=Na.exec(a.type);return b?a.type=b[1]:a.removeAttribute(\"type\"),a}function o(a,b){for(var c=a.length,d=0;c>d;d++)qa.set(a[d],\"globalEval\",!b||qa.get(b[d],\"globalEval\"))}function p(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(qa.hasData(a)&&(f=qa.access(a),g=qa.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)fa.event.add(b,e,j[e][c])}pa.hasData(a)&&(h=pa.access(a),i=fa.extend({},h),pa.set(b,i))}}function q(a,c){var d=a.getElementsByTagName?a.getElementsByTagName(c||\"*\"):a.querySelectorAll?a.querySelectorAll(c||\"*\"):[];return c===b||c&&fa.nodeName(a,c)?fa.merge([a],d):d}function r(a,b){var c=b.nodeName.toLowerCase();\"input\"===c&&Ka.test(a.type)?b.checked=a.checked:(\"input\"===c||\"textarea\"===c)&&(b.defaultValue=a.defaultValue)}function s(a,b){if(b in a)return b;for(var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=_a.length;e--;)if(b=_a[e]+c,b in a)return b;return d}function t(a,b){return a=b||a,\"none\"===fa.css(a,\"display\")||!fa.contains(a.ownerDocument,a)}function u(b){return a.getComputedStyle(b,null)}function v(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=qa.get(d,\"olddisplay\"),c=d.style.display,b?(f[g]||\"none\"!==c||(d.style.display=\"\"),\"\"===d.style.display&&t(d)&&(f[g]=qa.access(d,\"olddisplay\",z(d.nodeName)))):f[g]||(e=t(d),(c&&\"none\"!==c||!e)&&qa.set(d,\"olddisplay\",e?c:fa.css(d,\"display\"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&\"none\"!==d.style.display&&\"\"!==d.style.display||(d.style.display=b?f[g]||\"\":\"none\"));return a}function w(a,b,c){var d=Ua.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||\"px\"):b}function x(a,b,c,d,e){for(var f=c===(d?\"border\":\"content\")?4:\"width\"===b?1:0,g=0;4>f;f+=2)\"margin\"===c&&(g+=fa.css(a,c+$a[f],!0,e)),d?(\"content\"===c&&(g-=fa.css(a,\"padding\"+$a[f],!0,e)),\"margin\"!==c&&(g-=fa.css(a,\"border\"+$a[f]+\"Width\",!0,e))):(g+=fa.css(a,\"padding\"+$a[f],!0,e),\"padding\"!==c&&(g+=fa.css(a,\"border\"+$a[f]+\"Width\",!0,e)));return g}function y(a,b,c){var d=!0,e=\"width\"===b?a.offsetWidth:a.offsetHeight,f=u(a),g=fa.support.boxSizing&&\"border-box\"===fa.css(a,\"boxSizing\",!1,f);if(0>=e||null==e){if(e=Qa(a,b,f),(0>e||null==e)&&(e=a.style[b]),Va.test(e))return e;d=g&&(fa.support.boxSizingReliable||e===a.style[b]),e=parseFloat(e)||0}return e+x(a,b,c||(g?\"border\":\"content\"),d,f)+\"px\"}function z(a){var b=T,c=Xa[a];return c||(c=A(a,b),\"none\"!==c&&c||(Ra=(Ra||fa(\"<iframe frameborder='0' width='0' height='0'/>\").css(\"cssText\",\"display:block !important\")).appendTo(b.documentElement),b=(Ra[0].contentWindow||Ra[0].contentDocument).document,b.write(\"<!doctype html><html><body>\"),b.close(),c=A(a,b),Ra.detach()),Xa[a]=c),c}function A(a,b){var c=fa(b.createElement(a)).appendTo(b.body),d=fa.css(c[0],\"display\");return c.remove(),d}function B(a,b,c,d){var e;if(fa.isArray(b))fa.each(b,function(b,e){c||bb.test(a)?d(a,e):B(a+\"[\"+(\"object\"==typeof e?b:\"\")+\"]\",e,c,d)});else if(c||\"object\"!==fa.type(b))d(a,b);else for(e in b)B(a+\"[\"+e+\"]\",b[e],c,d)}function C(a){return function(b,c){\"string\"!=typeof b&&(c=b,b=\"*\");var d,e=0,f=b.toLowerCase().match(ha)||[];if(fa.isFunction(c))for(;d=f[e++];)\"+\"===d[0]?(d=d.slice(1)||\"*\",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function D(a,b,c,d){function e(h){var i;return f[h]=!0,fa.each(a[h]||[],function(a,h){var j=h(b,c,d);return\"string\"!=typeof j||g||f[j]?g?!(i=j):void 0:(b.dataTypes.unshift(j),e(j),!1)}),i}var f={},g=a===sb;return e(b.dataTypes[0])||!f[\"*\"]&&e(\"*\")}function E(a,c){var d,e,f=fa.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((f[d]?a:e||(e={}))[d]=c[d]);return e&&fa.extend(!0,a,e),a}function F(a,c,d){for(var e,f,g,h,i=a.contents,j=a.dataTypes;\"*\"===j[0];)j.shift(),e===b&&(e=a.mimeType||c.getResponseHeader(\"Content-Type\"));if(e)for(f in i)if(i[f]&&i[f].test(e)){j.unshift(f);break}if(j[0]in d)g=j[0];else{for(f in d){if(!j[0]||a.converters[f+\" \"+j[0]]){g=f;break}h||(h=f)}g=g||h}return g?(g!==j[0]&&j.unshift(g),d[g]):void 0}function G(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];for(f=k.shift();f;)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if(\"*\"===f)f=i;else if(\"*\"!==i&&i!==f){if(g=j[i+\" \"+f]||j[\"* \"+f],!g)for(e in j)if(h=e.split(\" \"),h[1]===f&&(g=j[i+\" \"+h[0]]||j[\"* \"+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a[\"throws\"])b=g(b);else try{b=g(b)}catch(l){return{state:\"parsererror\",error:g?l:\"No conversion from \"+i+\" to \"+f}}}return{state:\"success\",data:b}}function H(){return setTimeout(function(){Bb=b}),Bb=fa.now()}function I(a,b,c){for(var d,e=(Hb[b]||[]).concat(Hb[\"*\"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function J(a,b,c){var d,e,f=0,g=Gb.length,h=fa.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Bb||H(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:fa.extend({},b),opts:fa.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:Bb||H(),duration:c.duration,tweens:[],createTween:function(b,c){var d=fa.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(K(k,j.opts.specialEasing);g>f;f++)if(d=Gb[f].call(j,a,k,j.opts))return d;return fa.map(k,I,j),fa.isFunction(j.opts.start)&&j.opts.start.call(a,j),fa.fx.timer(fa.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}function K(a,b){var c,d,e,f,g;for(c in a)if(d=fa.camelCase(c),e=b[d],f=a[c],fa.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=fa.cssHooks[d],g&&\"expand\"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function L(a,c,d){var e,f,g,h,i,j,k=this,l={},m=a.style,n=a.nodeType&&t(a),o=qa.get(a,\"fxshow\");d.queue||(i=fa._queueHooks(a,\"fx\"),null==i.unqueued&&(i.unqueued=0,j=i.empty.fire,i.empty.fire=function(){i.unqueued||j()}),i.unqueued++,k.always(function(){k.always(function(){i.unqueued--,fa.queue(a,\"fx\").length||i.empty.fire()})})),1===a.nodeType&&(\"height\"in c||\"width\"in c)&&(d.overflow=[m.overflow,m.overflowX,m.overflowY],\"inline\"===fa.css(a,\"display\")&&\"none\"===fa.css(a,\"float\")&&(m.display=\"inline-block\")),d.overflow&&(m.overflow=\"hidden\",k.always(function(){m.overflow=d.overflow[0],m.overflowX=d.overflow[1],m.overflowY=d.overflow[2]}));for(e in c)if(f=c[e],Db.exec(f)){if(delete c[e],g=g||\"toggle\"===f,f===(n?\"hide\":\"show\")){if(\"show\"!==f||!o||o[e]===b)continue;n=!0}l[e]=o&&o[e]||fa.style(a,e)}if(!fa.isEmptyObject(l)){o?\"hidden\"in o&&(n=o.hidden):o=qa.access(a,\"fxshow\",{}),g&&(o.hidden=!n),n?fa(a).show():k.done(function(){fa(a).hide()}),k.done(function(){var b;qa.remove(a,\"fxshow\");for(b in l)fa.style(a,b,l[b])});for(e in l)h=I(n?o[e]:0,e,k),e in o||(o[e]=h.start,n&&(h.end=h.start,h.start=\"width\"===e||\"height\"===e?1:0))}}function M(a,b,c,d,e){return new M.prototype.init(a,b,c,d,e)}function N(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=$a[e],d[\"margin\"+c]=d[\"padding\"+c]=a;return b&&(d.opacity=d.width=a),d}function O(a){return fa.isWindow(a)?a:9===a.nodeType&&a.defaultView}var P,Q,R=typeof b,S=a.location,T=a.document,U=T.documentElement,V=a.jQuery,W=a.$,X={},Y=[],Z=\"2.0.3\",$=Y.concat,_=Y.push,aa=Y.slice,ba=Y.indexOf,ca=X.toString,da=X.hasOwnProperty,ea=Z.trim,fa=function(a,b){return new fa.fn.init(a,b,P)},ga=/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source,ha=/\\S+/g,ia=/^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,ja=/^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/,ka=/^-ms-/,la=/-([\\da-z])/gi,ma=function(a,b){return b.toUpperCase()},na=function(){T.removeEventListener(\"DOMContentLoaded\",na,!1),a.removeEventListener(\"load\",na,!1),fa.ready()};fa.fn=fa.prototype={jquery:Z,constructor:fa,init:function(a,c,d){var e,f;if(!a)return this;if(\"string\"==typeof a){if(e=\"<\"===a.charAt(0)&&\">\"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:ia.exec(a),!e||!e[1]&&c)return!c||c.jquery?(c||d).find(a):this.constructor(c).find(a);if(e[1]){if(c=c instanceof fa?c[0]:c,fa.merge(this,fa.parseHTML(e[1],c&&c.nodeType?c.ownerDocument||c:T,!0)),ja.test(e[1])&&fa.isPlainObject(c))for(e in c)fa.isFunction(this[e])?this[e](c[e]):this.attr(e,c[e]);return this}return f=T.getElementById(e[2]),f&&f.parentNode&&(this.length=1,this[0]=f),this.context=T,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):fa.isFunction(a)?d.ready(a):(a.selector!==b&&(this.selector=a.selector,this.context=a.context),fa.makeArray(a,this))},selector:\"\",length:0,toArray:function(){return aa.call(this)},get:function(a){return null==a?this.toArray():0>a?this[this.length+a]:this[a]},pushStack:function(a){var b=fa.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return fa.each(this,a,b)},ready:function(a){return fa.ready.promise().done(a),this},slice:function(){return this.pushStack(aa.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},map:function(a){return this.pushStack(fa.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:_,sort:[].sort,splice:[].splice},fa.fn.init.prototype=fa.fn,fa.extend=fa.fn.extend=function(){var a,c,d,e,f,g,h=arguments[0]||{},i=1,j=arguments.length,k=!1;for(\"boolean\"==typeof h&&(k=h,h=arguments[1]||{},i=2),\"object\"==typeof h||fa.isFunction(h)||(h={}),j===i&&(h=this,--i);j>i;i++)if(null!=(a=arguments[i]))for(c in a)d=h[c],e=a[c],h!==e&&(k&&e&&(fa.isPlainObject(e)||(f=fa.isArray(e)))?(f?(f=!1,g=d&&fa.isArray(d)?d:[]):g=d&&fa.isPlainObject(d)?d:{},h[c]=fa.extend(k,g,e)):e!==b&&(h[c]=e));return h},fa.extend({expando:\"jQuery\"+(Z+Math.random()).replace(/\\D/g,\"\"),noConflict:function(b){return a.$===fa&&(a.$=W),b&&a.jQuery===fa&&(a.jQuery=V),fa},isReady:!1,readyWait:1,holdReady:function(a){a?fa.readyWait++:fa.ready(!0)},ready:function(a){(a===!0?--fa.readyWait:fa.isReady)||(fa.isReady=!0,a!==!0&&--fa.readyWait>0||(Q.resolveWith(T,[fa]),fa.fn.trigger&&fa(T).trigger(\"ready\").off(\"ready\")))},isFunction:function(a){return\"function\"===fa.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return null==a?String(a):\"object\"==typeof a||\"function\"==typeof a?X[ca.call(a)]||\"object\":typeof a},isPlainObject:function(a){if(\"object\"!==fa.type(a)||a.nodeType||fa.isWindow(a))return!1;try{if(a.constructor&&!da.call(a.constructor.prototype,\"isPrototypeOf\"))return!1}catch(b){return!1}return!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},error:function(a){throw new Error(a)},parseHTML:function(a,b,c){if(!a||\"string\"!=typeof a)return null;\"boolean\"==typeof b&&(c=b,b=!1),b=b||T;var d=ja.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=fa.buildFragment([a],b,e),e&&fa(e).remove(),fa.merge([],d.childNodes))},parseJSON:JSON.parse,parseXML:function(a){var c,d;if(!a||\"string\"!=typeof a)return null;try{d=new DOMParser,c=d.parseFromString(a,\"text/xml\")}catch(e){c=b}return(!c||c.getElementsByTagName(\"parsererror\").length)&&fa.error(\"Invalid XML: \"+a),c},noop:function(){},globalEval:function(a){var b,c=eval;a=fa.trim(a),a&&(1===a.indexOf(\"use strict\")?(b=T.createElement(\"script\"),b.text=a,T.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(ka,\"ms-\").replace(la,ma)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,d){var e,f=0,g=a.length,h=c(a);if(d){if(h)for(;g>f&&(e=b.apply(a[f],d),e!==!1);f++);else for(f in a)if(e=b.apply(a[f],d),e===!1)break}else if(h)for(;g>f&&(e=b.call(a[f],f,a[f]),e!==!1);f++);else for(f in a)if(e=b.call(a[f],f,a[f]),e===!1)break;return a},trim:function(a){return null==a?\"\":ea.call(a)},makeArray:function(a,b){var d=b||[];return null!=a&&(c(Object(a))?fa.merge(d,\"string\"==typeof a?[a]:a):_.call(d,a)),d},inArray:function(a,b,c){return null==b?-1:ba.call(b,a,c)},merge:function(a,c){var d=c.length,e=a.length,f=0;if(\"number\"==typeof d)for(;d>f;f++)a[e++]=c[f];else for(;c[f]!==b;)a[e++]=c[f++];return a.length=e,a},grep:function(a,b,c){var d,e=[],f=0,g=a.length;for(c=!!c;g>f;f++)d=!!b(a[f],f),c!==d&&e.push(a[f]);return e},map:function(a,b,d){var e,f=0,g=a.length,h=c(a),i=[];if(h)for(;g>f;f++)e=b(a[f],f,d),null!=e&&(i[i.length]=e);else for(f in a)e=b(a[f],f,d),null!=e&&(i[i.length]=e);return $.apply([],i)},guid:1,proxy:function(a,c){var d,e,f;return\"string\"==typeof c&&(d=a[c],c=a,a=d),fa.isFunction(a)?(e=aa.call(arguments,2),f=function(){return a.apply(c||this,e.concat(aa.call(arguments)))},f.guid=a.guid=a.guid||fa.guid++,f):b},access:function(a,c,d,e,f,g,h){var i=0,j=a.length,k=null==d;if(\"object\"===fa.type(d)){f=!0;for(i in d)fa.access(a,c,i,d[i],!0,g,h)}else if(e!==b&&(f=!0,fa.isFunction(e)||(h=!0),k&&(h?(c.call(a,e),c=null):(k=c,c=function(a,b,c){return k.call(fa(a),c)})),c))for(;j>i;i++)c(a[i],d,h?e:e.call(a[i],i,c(a[i],d)));return f?a:k?c.call(a):j?c(a[0],d):g},now:Date.now,swap:function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e}}),fa.ready.promise=function(b){return Q||(Q=fa.Deferred(),\"complete\"===T.readyState?setTimeout(fa.ready):(T.addEventListener(\"DOMContentLoaded\",na,!1),a.addEventListener(\"load\",na,!1))),Q.promise(b)},fa.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"),function(a,b){X[\"[object \"+b+\"]\"]=b.toLowerCase()}),P=fa(T),function(a,b){function c(a,b,c,d){var e,f,g,h,i,j,k,l,o,p;if((b?b.ownerDocument||b:O)!==G&&F(b),b=b||G,c=c||[],!a||\"string\"!=typeof a)return c;if(1!==(h=b.nodeType)&&9!==h)return[];if(I&&!d){if(e=ta.exec(a))if(g=e[1]){if(9===h){if(f=b.getElementById(g),!f||!f.parentNode)return c;if(f.id===g)return c.push(f),c}else if(b.ownerDocument&&(f=b.ownerDocument.getElementById(g))&&M(b,f)&&f.id===g)return c.push(f),c}else{if(e[2])return aa.apply(c,b.getElementsByTagName(a)),c;if((g=e[3])&&x.getElementsByClassName&&b.getElementsByClassName)return aa.apply(c,b.getElementsByClassName(g)),c}if(x.qsa&&(!J||!J.test(a))){if(l=k=N,o=b,p=9===h&&a,1===h&&\"object\"!==b.nodeName.toLowerCase()){for(j=m(a),(k=b.getAttribute(\"id\"))?l=k.replace(wa,\"\\\\$&\"):b.setAttribute(\"id\",l),l=\"[id='\"+l+\"'] \",i=j.length;i--;)j[i]=l+n(j[i]);o=na.test(a)&&b.parentNode||b,p=j.join(\",\")}if(p)try{return aa.apply(c,o.querySelectorAll(p)),c}catch(q){}finally{k||b.removeAttribute(\"id\")}}}return v(a.replace(ka,\"$1\"),b,c,d)}function d(){function a(c,d){return b.push(c+=\" \")>z.cacheLength&&delete a[b.shift()],a[c]=d}var b=[];return a}function e(a){return a[N]=!0,a}function f(a){var b=G.createElement(\"div\");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function g(a,b){for(var c=a.split(\"|\"),d=a.length;d--;)z.attrHandle[c[d]]=b}function h(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||X)-(~a.sourceIndex||X);if(d)return d;if(c)for(;c=c.nextSibling;)if(c===b)return-1;return a?1:-1}function i(a){return function(b){var c=b.nodeName.toLowerCase();return\"input\"===c&&b.type===a}}function j(a){return function(b){var c=b.nodeName.toLowerCase();return(\"input\"===c||\"button\"===c)&&b.type===a}}function k(a){return e(function(b){return b=+b,e(function(c,d){for(var e,f=a([],c.length,b),g=f.length;g--;)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function l(){}function m(a,b){var d,e,f,g,h,i,j,k=S[a+\" \"];if(k)return b?0:k.slice(0);for(h=a,i=[],j=z.preFilter;h;){(!d||(e=la.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),d=!1,(e=ma.exec(h))&&(d=e.shift(),f.push({value:d,type:e[0].replace(ka,\" \")}),h=h.slice(d.length));for(g in z.filter)!(e=ra[g].exec(h))||j[g]&&!(e=j[g](e))||(d=e.shift(),f.push({value:d,type:g,matches:e}),h=h.slice(d.length));if(!d)break}return b?h.length:h?c.error(a):S(a,i).slice(0)}function n(a){for(var b=0,c=a.length,d=\"\";c>b;b++)d+=a[b].value;return d}function o(a,b,c){var d=b.dir,e=c&&\"parentNode\"===d,f=Q++;return b.first?function(b,c,f){for(;b=b[d];)if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=P+\" \"+f;if(g){for(;b=b[d];)if((1===b.nodeType||e)&&a(b,c,g))return!0}else for(;b=b[d];)if(1===b.nodeType||e)if(j=b[N]||(b[N]={}),(i=j[d])&&i[0]===k){if((h=i[1])===!0||h===y)return h===!0}else if(i=j[d]=[k],i[1]=a(b,c,g)||y,i[1]===!0)return!0}}function p(a){return a.length>1?function(b,c,d){for(var e=a.length;e--;)if(!a[e](b,c,d))return!1;return!0}:a[0]}function q(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function r(a,b,c,d,f,g){return d&&!d[N]&&(d=r(d)),f&&!f[N]&&(f=r(f,g)),e(function(e,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=e||u(b||\"*\",h.nodeType?[h]:h,[]),r=!a||!e&&b?p:q(p,m,a,h,i),s=c?f||(e?a:o||d)?[]:g:r;if(c&&c(r,s,h,i),d)for(j=q(s,n),d(j,[],h,i),k=j.length;k--;)(l=j[k])&&(s[n[k]]=!(r[n[k]]=l));if(e){if(f||a){if(f){for(j=[],k=s.length;k--;)(l=s[k])&&j.push(r[k]=l);f(null,s=[],j,i)}for(k=s.length;k--;)(l=s[k])&&(j=f?ca.call(e,l):m[k])>-1&&(e[j]=!(g[j]=l))}}else s=q(s===g?s.splice(o,s.length):s),f?f(null,g,s,i):aa.apply(g,s)})}function s(a){for(var b,c,d,e=a.length,f=z.relative[a[0].type],g=f||z.relative[\" \"],h=f?1:0,i=o(function(a){return a===b},g,!0),j=o(function(a){return ca.call(b,a)>-1},g,!0),k=[function(a,c,d){return!f&&(d||c!==D)||((b=c).nodeType?i(a,c,d):j(a,c,d))}];e>h;h++)if(c=z.relative[a[h].type])k=[o(p(k),c)];else{if(c=z.filter[a[h].type].apply(null,a[h].matches),c[N]){for(d=++h;e>d&&!z.relative[a[d].type];d++);return r(h>1&&p(k),h>1&&n(a.slice(0,h-1).concat({value:\" \"===a[h-2].type?\"*\":\"\"})).replace(ka,\"$1\"),c,d>h&&s(a.slice(h,d)),e>d&&s(a=a.slice(d)),e>d&&n(a))}k.push(c)}return p(k)}function t(a,b){var d=0,f=b.length>0,g=a.length>0,h=function(e,h,i,j,k){var l,m,n,o=[],p=0,r=\"0\",s=e&&[],t=null!=k,u=D,v=e||g&&z.find.TAG(\"*\",k&&h.parentNode||h),w=P+=null==u?1:Math.random()||.1;for(t&&(D=h!==G&&h,y=d);null!=(l=v[r]);r++){if(g&&l){for(m=0;n=a[m++];)if(n(l,h,i)){j.push(l);break}t&&(P=w,y=++d)}f&&((l=!n&&l)&&p--,e&&s.push(l))}if(p+=r,f&&r!==p){for(m=0;n=b[m++];)n(s,o,h,i);if(e){if(p>0)for(;r--;)s[r]||o[r]||(o[r]=$.call(j));o=q(o)}aa.apply(j,o),t&&!e&&o.length>0&&p+b.length>1&&c.uniqueSort(j)}return t&&(P=w,D=u),s};return f?e(h):h}function u(a,b,d){for(var e=0,f=b.length;f>e;e++)c(a,b[e],d);return d}function v(a,b,c,d){var e,f,g,h,i,j=m(a);if(!d&&1===j.length){if(f=j[0]=j[0].slice(0),f.length>2&&\"ID\"===(g=f[0]).type&&x.getById&&9===b.nodeType&&I&&z.relative[f[1].type]){if(b=(z.find.ID(g.matches[0].replace(xa,ya),b)||[])[0],!b)return c;a=a.slice(f.shift().value.length)}for(e=ra.needsContext.test(a)?0:f.length;e--&&(g=f[e],!z.relative[h=g.type]);)if((i=z.find[h])&&(d=i(g.matches[0].replace(xa,ya),na.test(f[0].type)&&b.parentNode||b))){if(f.splice(e,1),a=d.length&&n(f),!a)return aa.apply(c,d),c;break}}return C(a,j)(d,b,!I,c,na.test(a)),c}var w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N=\"sizzle\"+-new Date,O=a.document,P=0,Q=0,R=d(),S=d(),T=d(),U=!1,V=function(a,b){return a===b?(U=!0,0):0},W=typeof b,X=1<<31,Y={}.hasOwnProperty,Z=[],$=Z.pop,_=Z.push,aa=Z.push,ba=Z.slice,ca=Z.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},da=\"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",ea=\"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",ga=\"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",ha=ga.replace(\"w\",\"w#\"),ia=\"\\\\[\"+ea+\"*(\"+ga+\")\"+ea+\"*(?:([*^$|!~]?=)\"+ea+\"*(?:(['\\\"])((?:\\\\\\\\.|[^\\\\\\\\])*?)\\\\3|(\"+ha+\")|)|)\"+ea+\"*\\\\]\",ja=\":(\"+ga+\")(?:\\\\(((['\\\"])((?:\\\\\\\\.|[^\\\\\\\\])*?)\\\\3|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\"+ia.replace(3,8)+\")*)|.*)\\\\)|)\",ka=new RegExp(\"^\"+ea+\"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\"+ea+\"+$\",\"g\"),la=new RegExp(\"^\"+ea+\"*,\"+ea+\"*\"),ma=new RegExp(\"^\"+ea+\"*([>+~]|\"+ea+\")\"+ea+\"*\"),na=new RegExp(ea+\"*[+~]\"),oa=new RegExp(\"=\"+ea+\"*([^\\\\]'\\\"]*)\"+ea+\"*\\\\]\",\"g\"),pa=new RegExp(ja),qa=new RegExp(\"^\"+ha+\"$\"),ra={ID:new RegExp(\"^#(\"+ga+\")\"),CLASS:new RegExp(\"^\\\\.(\"+ga+\")\"),TAG:new RegExp(\"^(\"+ga.replace(\"w\",\"w*\")+\")\"),ATTR:new RegExp(\"^\"+ia),PSEUDO:new RegExp(\"^\"+ja),CHILD:new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\"+ea+\"*(even|odd|(([+-]|)(\\\\d*)n|)\"+ea+\"*(?:([+-]|)\"+ea+\"*(\\\\d+)|))\"+ea+\"*\\\\)|)\",\"i\"),bool:new RegExp(\"^(?:\"+da+\")$\",\"i\"),needsContext:new RegExp(\"^\"+ea+\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\"+ea+\"*((?:-\\\\d)?\\\\d*)\"+ea+\"*\\\\)|)(?=[^-]|$)\",\"i\")},sa=/^[^{]+\\{\\s*\\[native \\w/,ta=/^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,ua=/^(?:input|select|textarea|button)$/i,va=/^h\\d$/i,wa=/'|\\\\/g,xa=new RegExp(\"\\\\\\\\([\\\\da-f]{1,6}\"+ea+\"?|(\"+ea+\")|.)\",\"ig\"),ya=function(a,b,c){var d=\"0x\"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{aa.apply(Z=ba.call(O.childNodes),O.childNodes),Z[O.childNodes.length].nodeType}catch(za){aa={apply:Z.length?function(a,b){_.apply(a,ba.call(b))}:function(a,b){for(var c=a.length,d=0;a[c++]=b[d++];);a.length=c-1}}}B=c.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?\"HTML\"!==b.nodeName:!1},x=c.support={},F=c.setDocument=function(a){var b=a?a.ownerDocument||a:O,c=b.defaultView;return b!==G&&9===b.nodeType&&b.documentElement?(G=b,H=b.documentElement,I=!B(b),c&&c.attachEvent&&c!==c.top&&c.attachEvent(\"onbeforeunload\",function(){F()}),x.attributes=f(function(a){return a.className=\"i\",!a.getAttribute(\"className\")}),x.getElementsByTagName=f(function(a){return a.appendChild(b.createComment(\"\")),!a.getElementsByTagName(\"*\").length}),x.getElementsByClassName=f(function(a){return a.innerHTML=\"<div class='a'></div><div class='a i'></div>\",a.firstChild.className=\"i\",2===a.getElementsByClassName(\"i\").length}),x.getById=f(function(a){return H.appendChild(a).id=N,!b.getElementsByName||!b.getElementsByName(N).length}),x.getById?(z.find.ID=function(a,b){if(typeof b.getElementById!==W&&I){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},z.filter.ID=function(a){var b=a.replace(xa,ya);return function(a){return a.getAttribute(\"id\")===b}}):(delete z.find.ID,z.filter.ID=function(a){var b=a.replace(xa,ya);return function(a){var c=typeof a.getAttributeNode!==W&&a.getAttributeNode(\"id\");return c&&c.value===b}}),z.find.TAG=x.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==W?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if(\"*\"===a){for(;c=f[e++];)1===c.nodeType&&d.push(c);return d}return f},z.find.CLASS=x.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==W&&I?b.getElementsByClassName(a):void 0},K=[],J=[],(x.qsa=sa.test(b.querySelectorAll))&&(f(function(a){a.innerHTML=\"<select><option selected=''></option></select>\",a.querySelectorAll(\"[selected]\").length||J.push(\"\\\\[\"+ea+\"*(?:value|\"+da+\")\"),a.querySelectorAll(\":checked\").length||J.push(\":checked\")}),f(function(a){var c=b.createElement(\"input\");c.setAttribute(\"type\",\"hidden\"),a.appendChild(c).setAttribute(\"t\",\"\"),a.querySelectorAll(\"[t^='']\").length&&J.push(\"[*^$]=\"+ea+\"*(?:''|\\\"\\\")\"),a.querySelectorAll(\":enabled\").length||J.push(\":enabled\",\":disabled\"),a.querySelectorAll(\"*,:x\"),J.push(\",.*:\")})),(x.matchesSelector=sa.test(L=H.webkitMatchesSelector||H.mozMatchesSelector||H.oMatchesSelector||H.msMatchesSelector))&&f(function(a){x.disconnectedMatch=L.call(a,\"div\"),L.call(a,\"[s!='']:x\"),K.push(\"!=\",ja)}),J=J.length&&new RegExp(J.join(\"|\")),K=K.length&&new RegExp(K.join(\"|\")),M=sa.test(H.contains)||H.compareDocumentPosition?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)for(;b=b.parentNode;)if(b===a)return!0;return!1},V=H.compareDocumentPosition?function(a,c){if(a===c)return U=!0,0;var d=c.compareDocumentPosition&&a.compareDocumentPosition&&a.compareDocumentPosition(c);return d?1&d||!x.sortDetached&&c.compareDocumentPosition(a)===d?a===b||M(O,a)?-1:c===b||M(O,c)?1:E?ca.call(E,a)-ca.call(E,c):0:4&d?-1:1:a.compareDocumentPosition?-1:1}:function(a,c){var d,e=0,f=a.parentNode,g=c.parentNode,i=[a],j=[c];if(a===c)return U=!0,0;if(!f||!g)return a===b?-1:c===b?1:f?-1:g?1:E?ca.call(E,a)-ca.call(E,c):0;if(f===g)return h(a,c);for(d=a;d=d.parentNode;)i.unshift(d);for(d=c;d=d.parentNode;)j.unshift(d);for(;i[e]===j[e];)e++;return e?h(i[e],j[e]):i[e]===O?-1:j[e]===O?1:0},b):G},c.matches=function(a,b){return c(a,null,null,b)},c.matchesSelector=function(a,b){if((a.ownerDocument||a)!==G&&F(a),b=b.replace(oa,\"='$1']\"),x.matchesSelector&&I&&(!K||!K.test(b))&&(!J||!J.test(b)))try{var d=L.call(a,b);if(d||x.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return c(b,G,null,[a]).length>0},c.contains=function(a,b){return(a.ownerDocument||a)!==G&&F(a),M(a,b)},c.attr=function(a,c){(a.ownerDocument||a)!==G&&F(a);var d=z.attrHandle[c.toLowerCase()],e=d&&Y.call(z.attrHandle,c.toLowerCase())?d(a,c,!I):b;return e===b?x.attributes||!I?a.getAttribute(c):(e=a.getAttributeNode(c))&&e.specified?e.value:null:e},c.error=function(a){throw new Error(\"Syntax error, unrecognized expression: \"+a)},c.uniqueSort=function(a){var b,c=[],d=0,e=0;if(U=!x.detectDuplicates,E=!x.sortStable&&a.slice(0),a.sort(V),U){for(;b=a[e++];)b===a[e]&&(d=c.push(e));for(;d--;)a.splice(c[d],1)}return a},A=c.getText=function(a){var b,c=\"\",d=0,e=a.nodeType;if(e){if(1===e||9===e||11===e){if(\"string\"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=A(a)}else if(3===e||4===e)return a.nodeValue}else for(;b=a[d];d++)c+=A(b);return c},z=c.selectors={cacheLength:50,createPseudo:e,match:ra,attrHandle:{},find:{},relative:{\">\":{dir:\"parentNode\",first:!0},\" \":{dir:\"parentNode\"},\"+\":{dir:\"previousSibling\",first:!0},\"~\":{dir:\"previousSibling\"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(xa,ya),a[3]=(a[4]||a[5]||\"\").replace(xa,ya),\"~=\"===a[2]&&(a[3]=\" \"+a[3]+\" \"),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),\"nth\"===a[1].slice(0,3)?(a[3]||c.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*(\"even\"===a[3]||\"odd\"===a[3])),a[5]=+(a[7]+a[8]||\"odd\"===a[3])):a[3]&&c.error(a[0]),a},PSEUDO:function(a){var c,d=!a[5]&&a[2];return ra.CHILD.test(a[0])?null:(a[3]&&a[4]!==b?a[2]=a[4]:d&&pa.test(d)&&(c=m(d,!0))&&(c=d.indexOf(\")\",d.length-c)-d.length)&&(a[0]=a[0].slice(0,c),a[2]=d.slice(0,c)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(xa,ya).toLowerCase();return\"*\"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=R[a+\" \"];return b||(b=new RegExp(\"(^|\"+ea+\")\"+a+\"(\"+ea+\"|$)\"))&&R(a,function(a){return b.test(\"string\"==typeof a.className&&a.className||typeof a.getAttribute!==W&&a.getAttribute(\"class\")||\"\")})},ATTR:function(a,b,d){return function(e){var f=c.attr(e,a);return null==f?\"!=\"===b:b?(f+=\"\",\"=\"===b?f===d:\"!=\"===b?f!==d:\"^=\"===b?d&&0===f.indexOf(d):\"*=\"===b?d&&f.indexOf(d)>-1:\"$=\"===b?d&&f.slice(-d.length)===d:\"~=\"===b?(\" \"+f+\" \").indexOf(d)>-1:\"|=\"===b?f===d||f.slice(0,d.length+1)===d+\"-\":!1):!0}},CHILD:function(a,b,c,d,e){var f=\"nth\"!==a.slice(0,3),g=\"last\"!==a.slice(-4),h=\"of-type\"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?\"nextSibling\":\"previousSibling\",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){for(;p;){for(l=b;l=l[p];)if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p=\"only\"===a&&!o&&\"nextSibling\"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){for(k=q[N]||(q[N]={}),j=k[a]||[],n=j[0]===P&&j[1],m=j[0]===P&&j[2],l=n&&q.childNodes[n];l=++n&&l&&l[p]||(m=n=0)||o.pop();)if(1===l.nodeType&&++m&&l===b){k[a]=[P,n,m];break}}else if(s&&(j=(b[N]||(b[N]={}))[a])&&j[0]===P)m=j[1];else for(;(l=++n&&l&&l[p]||(m=n=0)||o.pop())&&((h?l.nodeName.toLowerCase()!==r:1!==l.nodeType)||!++m||(s&&((l[N]||(l[N]={}))[a]=[P,m]),l!==b)););return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var d,f=z.pseudos[a]||z.setFilters[a.toLowerCase()]||c.error(\"unsupported pseudo: \"+a);return f[N]?f(b):f.length>1?(d=[a,a,\"\",b],z.setFilters.hasOwnProperty(a.toLowerCase())?e(function(a,c){for(var d,e=f(a,b),g=e.length;g--;)d=ca.call(a,e[g]),a[d]=!(c[d]=e[g])}):function(a){return f(a,0,d)}):f}},pseudos:{not:e(function(a){var b=[],c=[],d=C(a.replace(ka,\"$1\"));return d[N]?e(function(a,b,c,e){for(var f,g=d(a,null,e,[]),h=a.length;h--;)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:e(function(a){return function(b){return c(a,b).length>0}}),contains:e(function(a){return function(b){return(b.textContent||b.innerText||A(b)).indexOf(a)>-1}}),lang:e(function(a){return qa.test(a||\"\")||c.error(\"unsupported lang: \"+a),a=a.replace(xa,ya).toLowerCase(),function(b){var c;do if(c=I?b.lang:b.getAttribute(\"xml:lang\")||b.getAttribute(\"lang\"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+\"-\");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===H},focus:function(a){return a===G.activeElement&&(!G.hasFocus||G.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return\"input\"===b&&!!a.checked||\"option\"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeName>\"@\"||3===a.nodeType||4===a.nodeType)return!1;return!0},parent:function(a){return!z.pseudos.empty(a)},header:function(a){return va.test(a.nodeName)},input:function(a){return ua.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return\"input\"===b&&\"button\"===a.type||\"button\"===b},text:function(a){var b;return\"input\"===a.nodeName.toLowerCase()&&\"text\"===a.type&&(null==(b=a.getAttribute(\"type\"))||b.toLowerCase()===a.type)},first:k(function(){return[0]}),last:k(function(a,b){return[b-1]}),eq:k(function(a,b,c){return[0>c?c+b:c]}),even:k(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:k(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:k(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:k(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},z.pseudos.nth=z.pseudos.eq;for(w in{\nradio:!0,checkbox:!0,file:!0,password:!0,image:!0})z.pseudos[w]=i(w);for(w in{submit:!0,reset:!0})z.pseudos[w]=j(w);l.prototype=z.filters=z.pseudos,z.setFilters=new l,C=c.compile=function(a,b){var c,d=[],e=[],f=T[a+\" \"];if(!f){for(b||(b=m(a)),c=b.length;c--;)f=s(b[c]),f[N]?d.push(f):e.push(f);f=T(a,t(e,d))}return f},x.sortStable=N.split(\"\").sort(V).join(\"\")===N,x.detectDuplicates=U,F(),x.sortDetached=f(function(a){return 1&a.compareDocumentPosition(G.createElement(\"div\"))}),f(function(a){return a.innerHTML=\"<a href='#'></a>\",\"#\"===a.firstChild.getAttribute(\"href\")})||g(\"type|href|height|width\",function(a,b,c){return c?void 0:a.getAttribute(b,\"type\"===b.toLowerCase()?1:2)}),x.attributes&&f(function(a){return a.innerHTML=\"<input/>\",a.firstChild.setAttribute(\"value\",\"\"),\"\"===a.firstChild.getAttribute(\"value\")})||g(\"value\",function(a,b,c){return c||\"input\"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),f(function(a){return null==a.getAttribute(\"disabled\")})||g(da,function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&d.specified?d.value:a[b]===!0?b.toLowerCase():null}),fa.find=c,fa.expr=c.selectors,fa.expr[\":\"]=fa.expr.pseudos,fa.unique=c.uniqueSort,fa.text=c.getText,fa.isXMLDoc=c.isXML,fa.contains=c.contains}(a);var oa={};fa.Callbacks=function(a){a=\"string\"==typeof a?oa[a]||d(a):fa.extend({},a);var c,e,f,g,h,i,j=[],k=!a.once&&[],l=function(b){for(c=a.memory&&b,e=!0,i=g||0,g=0,h=j.length,f=!0;j&&h>i;i++)if(j[i].apply(b[0],b[1])===!1&&a.stopOnFalse){c=!1;break}f=!1,j&&(k?k.length&&l(k.shift()):c?j=[]:m.disable())},m={add:function(){if(j){var b=j.length;!function d(b){fa.each(b,function(b,c){var e=fa.type(c);\"function\"===e?a.unique&&m.has(c)||j.push(c):c&&c.length&&\"string\"!==e&&d(c)})}(arguments),f?h=j.length:c&&(g=b,l(c))}return this},remove:function(){return j&&fa.each(arguments,function(a,b){for(var c;(c=fa.inArray(b,j,c))>-1;)j.splice(c,1),f&&(h>=c&&h--,i>=c&&i--)}),this},has:function(a){return a?fa.inArray(a,j)>-1:!(!j||!j.length)},empty:function(){return j=[],h=0,this},disable:function(){return j=k=c=b,this},disabled:function(){return!j},lock:function(){return k=b,c||m.disable(),this},locked:function(){return!k},fireWith:function(a,b){return!j||e&&!k||(b=b||[],b=[a,b.slice?b.slice():b],f?k.push(b):l(b)),this},fire:function(){return m.fireWith(this,arguments),this},fired:function(){return!!e}};return m},fa.extend({Deferred:function(a){var b=[[\"resolve\",\"done\",fa.Callbacks(\"once memory\"),\"resolved\"],[\"reject\",\"fail\",fa.Callbacks(\"once memory\"),\"rejected\"],[\"notify\",\"progress\",fa.Callbacks(\"memory\")]],c=\"pending\",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return fa.Deferred(function(c){fa.each(b,function(b,f){var g=f[0],h=fa.isFunction(a[b])&&a[b];e[f[1]](function(){var a=h&&h.apply(this,arguments);a&&fa.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[g+\"With\"](this===d?c.promise():this,h?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?fa.extend(a,d):d}},e={};return d.pipe=d.then,fa.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+\"With\"](this===e?d:this,arguments),this},e[f[0]+\"With\"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b,c,d,e=0,f=aa.call(arguments),g=f.length,h=1!==g||a&&fa.isFunction(a.promise)?g:0,i=1===h?a:fa.Deferred(),j=function(a,c,d){return function(e){c[a]=this,d[a]=arguments.length>1?aa.call(arguments):e,d===b?i.notifyWith(c,d):--h||i.resolveWith(c,d)}};if(g>1)for(b=new Array(g),c=new Array(g),d=new Array(g);g>e;e++)f[e]&&fa.isFunction(f[e].promise)?f[e].promise().done(j(e,d,f)).fail(i.reject).progress(j(e,c,b)):--h;return h||i.resolveWith(d,f),i.promise()}}),fa.support=function(b){var c=T.createElement(\"input\"),d=T.createDocumentFragment(),e=T.createElement(\"div\"),f=T.createElement(\"select\"),g=f.appendChild(T.createElement(\"option\"));return c.type?(c.type=\"checkbox\",b.checkOn=\"\"!==c.value,b.optSelected=g.selected,b.reliableMarginRight=!0,b.boxSizingReliable=!0,b.pixelPosition=!1,c.checked=!0,b.noCloneChecked=c.cloneNode(!0).checked,f.disabled=!0,b.optDisabled=!g.disabled,c=T.createElement(\"input\"),c.value=\"t\",c.type=\"radio\",b.radioValue=\"t\"===c.value,c.setAttribute(\"checked\",\"t\"),c.setAttribute(\"name\",\"t\"),d.appendChild(c),b.checkClone=d.cloneNode(!0).cloneNode(!0).lastChild.checked,b.focusinBubbles=\"onfocusin\"in a,e.style.backgroundClip=\"content-box\",e.cloneNode(!0).style.backgroundClip=\"\",b.clearCloneStyle=\"content-box\"===e.style.backgroundClip,fa(function(){var c,d,f=\"padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box\",g=T.getElementsByTagName(\"body\")[0];g&&(c=T.createElement(\"div\"),c.style.cssText=\"border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px\",g.appendChild(c).appendChild(e),e.innerHTML=\"\",e.style.cssText=\"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%\",fa.swap(g,null!=g.style.zoom?{zoom:1}:{},function(){b.boxSizing=4===e.offsetWidth}),a.getComputedStyle&&(b.pixelPosition=\"1%\"!==(a.getComputedStyle(e,null)||{}).top,b.boxSizingReliable=\"4px\"===(a.getComputedStyle(e,null)||{width:\"4px\"}).width,d=e.appendChild(T.createElement(\"div\")),d.style.cssText=e.style.cssText=f,d.style.marginRight=d.style.width=\"0\",e.style.width=\"1px\",b.reliableMarginRight=!parseFloat((a.getComputedStyle(d,null)||{}).marginRight)),g.removeChild(c))}),b):b}({});var pa,qa,ra=/(?:\\{[\\s\\S]*\\}|\\[[\\s\\S]*\\])$/,sa=/([A-Z])/g;e.uid=1,e.accepts=function(a){return a.nodeType?1===a.nodeType||9===a.nodeType:!0},e.prototype={key:function(a){if(!e.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=e.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,fa.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if(\"string\"==typeof b)f[b]=c;else if(fa.isEmptyObject(f))fa.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,c){var d=this.cache[this.key(a)];return c===b?d:d[c]},access:function(a,c,d){var e;return c===b||c&&\"string\"==typeof c&&d===b?(e=this.get(a,c),e!==b?e:this.get(a,fa.camelCase(c))):(this.set(a,c,d),d!==b?d:c)},remove:function(a,c){var d,e,f,g=this.key(a),h=this.cache[g];if(c===b)this.cache[g]={};else{fa.isArray(c)?e=c.concat(c.map(fa.camelCase)):(f=fa.camelCase(c),c in h?e=[c,f]:(e=f,e=e in h?[e]:e.match(ha)||[])),d=e.length;for(;d--;)delete h[e[d]]}},hasData:function(a){return!fa.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}},pa=new e,qa=new e,fa.extend({acceptData:e.accepts,hasData:function(a){return pa.hasData(a)||qa.hasData(a)},data:function(a,b,c){return pa.access(a,b,c)},removeData:function(a,b){pa.remove(a,b)},_data:function(a,b,c){return qa.access(a,b,c)},_removeData:function(a,b){qa.remove(a,b)}}),fa.fn.extend({data:function(a,c){var d,e,g=this[0],h=0,i=null;if(a===b){if(this.length&&(i=pa.get(g),1===g.nodeType&&!qa.get(g,\"hasDataAttrs\"))){for(d=g.attributes;h<d.length;h++)e=d[h].name,0===e.indexOf(\"data-\")&&(e=fa.camelCase(e.slice(5)),f(g,e,i[e]));qa.set(g,\"hasDataAttrs\",!0)}return i}return\"object\"==typeof a?this.each(function(){pa.set(this,a)}):fa.access(this,function(c){var d,e=fa.camelCase(a);if(g&&c===b){if(d=pa.get(g,a),d!==b)return d;if(d=pa.get(g,e),d!==b)return d;if(d=f(g,e,b),d!==b)return d}else this.each(function(){var d=pa.get(this,e);pa.set(this,e,c),-1!==a.indexOf(\"-\")&&d!==b&&pa.set(this,a,c)})},null,c,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){pa.remove(this,a)})}}),fa.extend({queue:function(a,b,c){var d;return a?(b=(b||\"fx\")+\"queue\",d=qa.get(a,b),c&&(!d||fa.isArray(c)?d=qa.access(a,b,fa.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||\"fx\";var c=fa.queue(a,b),d=c.length,e=c.shift(),f=fa._queueHooks(a,b),g=function(){fa.dequeue(a,b)};\"inprogress\"===e&&(e=c.shift(),d--),e&&(\"fx\"===b&&c.unshift(\"inprogress\"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+\"queueHooks\";return qa.get(a,c)||qa.access(a,c,{empty:fa.Callbacks(\"once memory\").add(function(){qa.remove(a,[b+\"queue\",c])})})}}),fa.fn.extend({queue:function(a,c){var d=2;return\"string\"!=typeof a&&(c=a,a=\"fx\",d--),arguments.length<d?fa.queue(this[0],a):c===b?this:this.each(function(){var b=fa.queue(this,a,c);fa._queueHooks(this,a),\"fx\"===a&&\"inprogress\"!==b[0]&&fa.dequeue(this,a)})},dequeue:function(a){return this.each(function(){fa.dequeue(this,a)})},delay:function(a,b){return a=fa.fx?fa.fx.speeds[a]||a:a,b=b||\"fx\",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||\"fx\",[])},promise:function(a,c){var d,e=1,f=fa.Deferred(),g=this,h=this.length,i=function(){--e||f.resolveWith(g,[g])};for(\"string\"!=typeof a&&(c=a,a=b),a=a||\"fx\";h--;)d=qa.get(g[h],a+\"queueHooks\"),d&&d.empty&&(e++,d.empty.add(i));return i(),f.promise(c)}});var ta,ua,va=/[\\t\\r\\n\\f]/g,wa=/\\r/g,xa=/^(?:input|select|textarea|button)$/i;fa.fn.extend({attr:function(a,b){return fa.access(this,fa.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){fa.removeAttr(this,a)})},prop:function(a,b){return fa.access(this,fa.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[fa.propFix[a]||a]})},addClass:function(a){var b,c,d,e,f,g=0,h=this.length,i=\"string\"==typeof a&&a;if(fa.isFunction(a))return this.each(function(b){fa(this).addClass(a.call(this,b,this.className))});if(i)for(b=(a||\"\").match(ha)||[];h>g;g++)if(c=this[g],d=1===c.nodeType&&(c.className?(\" \"+c.className+\" \").replace(va,\" \"):\" \")){for(f=0;e=b[f++];)d.indexOf(\" \"+e+\" \")<0&&(d+=e+\" \");c.className=fa.trim(d)}return this},removeClass:function(a){var b,c,d,e,f,g=0,h=this.length,i=0===arguments.length||\"string\"==typeof a&&a;if(fa.isFunction(a))return this.each(function(b){fa(this).removeClass(a.call(this,b,this.className))});if(i)for(b=(a||\"\").match(ha)||[];h>g;g++)if(c=this[g],d=1===c.nodeType&&(c.className?(\" \"+c.className+\" \").replace(va,\" \"):\"\")){for(f=0;e=b[f++];)for(;d.indexOf(\" \"+e+\" \")>=0;)d=d.replace(\" \"+e+\" \",\" \");c.className=a?fa.trim(d):\"\"}return this},toggleClass:function(a,b){var c=typeof a;return\"boolean\"==typeof b&&\"string\"===c?b?this.addClass(a):this.removeClass(a):fa.isFunction(a)?this.each(function(c){fa(this).toggleClass(a.call(this,c,this.className,b),b)}):this.each(function(){if(\"string\"===c)for(var b,d=0,e=fa(this),f=a.match(ha)||[];b=f[d++];)e.hasClass(b)?e.removeClass(b):e.addClass(b);else(c===R||\"boolean\"===c)&&(this.className&&qa.set(this,\"__className__\",this.className),this.className=this.className||a===!1?\"\":qa.get(this,\"__className__\")||\"\")})},hasClass:function(a){for(var b=\" \"+a+\" \",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(\" \"+this[c].className+\" \").replace(va,\" \").indexOf(b)>=0)return!0;return!1},val:function(a){var c,d,e,f=this[0];{if(arguments.length)return e=fa.isFunction(a),this.each(function(d){var f;1===this.nodeType&&(f=e?a.call(this,d,fa(this).val()):a,null==f?f=\"\":\"number\"==typeof f?f+=\"\":fa.isArray(f)&&(f=fa.map(f,function(a){return null==a?\"\":a+\"\"})),c=fa.valHooks[this.type]||fa.valHooks[this.nodeName.toLowerCase()],c&&\"set\"in c&&c.set(this,f,\"value\")!==b||(this.value=f))});if(f)return c=fa.valHooks[f.type]||fa.valHooks[f.nodeName.toLowerCase()],c&&\"get\"in c&&(d=c.get(f,\"value\"))!==b?d:(d=f.value,\"string\"==typeof d?d.replace(wa,\"\"):null==d?\"\":d)}}}),fa.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f=\"select-one\"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],(c.selected||i===e)&&(fa.support.optDisabled?!c.disabled:null===c.getAttribute(\"disabled\"))&&(!c.parentNode.disabled||!fa.nodeName(c.parentNode,\"optgroup\"))){if(b=fa(c).val(),f)return b;g.push(b)}return g},set:function(a,b){for(var c,d,e=a.options,f=fa.makeArray(b),g=e.length;g--;)d=e[g],(d.selected=fa.inArray(fa(d).val(),f)>=0)&&(c=!0);return c||(a.selectedIndex=-1),f}}},attr:function(a,c,d){var e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return typeof a.getAttribute===R?fa.prop(a,c,d):(1===g&&fa.isXMLDoc(a)||(c=c.toLowerCase(),e=fa.attrHooks[c]||(fa.expr.match.bool.test(c)?ua:ta)),d===b?e&&\"get\"in e&&null!==(f=e.get(a,c))?f:(f=fa.find.attr(a,c),null==f?b:f):null!==d?e&&\"set\"in e&&(f=e.set(a,d,c))!==b?f:(a.setAttribute(c,d+\"\"),d):void fa.removeAttr(a,c))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(ha);if(f&&1===a.nodeType)for(;c=f[e++];)d=fa.propFix[c]||c,fa.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)},attrHooks:{type:{set:function(a,b){if(!fa.support.radioValue&&\"radio\"===b&&fa.nodeName(a,\"input\")){var c=a.value;return a.setAttribute(\"type\",b),c&&(a.value=c),b}}}},propFix:{\"for\":\"htmlFor\",\"class\":\"className\"},prop:function(a,c,d){var e,f,g,h=a.nodeType;if(a&&3!==h&&8!==h&&2!==h)return g=1!==h||!fa.isXMLDoc(a),g&&(c=fa.propFix[c]||c,f=fa.propHooks[c]),d!==b?f&&\"set\"in f&&(e=f.set(a,d,c))!==b?e:a[c]=d:f&&\"get\"in f&&null!==(e=f.get(a,c))?e:a[c]},propHooks:{tabIndex:{get:function(a){return a.hasAttribute(\"tabindex\")||xa.test(a.nodeName)||a.href?a.tabIndex:-1}}}}),ua={set:function(a,b,c){return b===!1?fa.removeAttr(a,c):a.setAttribute(c,c),c}},fa.each(fa.expr.match.bool.source.match(/\\w+/g),function(a,c){var d=fa.expr.attrHandle[c]||fa.find.attr;fa.expr.attrHandle[c]=function(a,c,e){var f=fa.expr.attrHandle[c],g=e?b:(fa.expr.attrHandle[c]=b)!=d(a,c,e)?c.toLowerCase():null;return fa.expr.attrHandle[c]=f,g}}),fa.support.optSelected||(fa.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null}}),fa.each([\"tabIndex\",\"readOnly\",\"maxLength\",\"cellSpacing\",\"cellPadding\",\"rowSpan\",\"colSpan\",\"useMap\",\"frameBorder\",\"contentEditable\"],function(){fa.propFix[this.toLowerCase()]=this}),fa.each([\"radio\",\"checkbox\"],function(){fa.valHooks[this]={set:function(a,b){return fa.isArray(b)?a.checked=fa.inArray(fa(a).val(),b)>=0:void 0}},fa.support.checkOn||(fa.valHooks[this].get=function(a){return null===a.getAttribute(\"value\")?\"on\":a.value})});var ya=/^key/,za=/^(?:mouse|contextmenu)|click/,Aa=/^(?:focusinfocus|focusoutblur)$/,Ba=/^([^.]*)(?:\\.(.+)|)$/;fa.event={global:{},add:function(a,c,d,e,f){var g,h,i,j,k,l,m,n,o,p,q,r=qa.get(a);if(r){for(d.handler&&(g=d,d=g.handler,f=g.selector),d.guid||(d.guid=fa.guid++),(j=r.events)||(j=r.events={}),(h=r.handle)||(h=r.handle=function(a){return typeof fa===R||a&&fa.event.triggered===a.type?b:fa.event.dispatch.apply(h.elem,arguments)},h.elem=a),c=(c||\"\").match(ha)||[\"\"],k=c.length;k--;)i=Ba.exec(c[k])||[],o=q=i[1],p=(i[2]||\"\").split(\".\").sort(),o&&(m=fa.event.special[o]||{},o=(f?m.delegateType:m.bindType)||o,m=fa.event.special[o]||{},l=fa.extend({type:o,origType:q,data:e,handler:d,guid:d.guid,selector:f,needsContext:f&&fa.expr.match.needsContext.test(f),namespace:p.join(\".\")},g),(n=j[o])||(n=j[o]=[],n.delegateCount=0,m.setup&&m.setup.call(a,e,p,h)!==!1||a.addEventListener&&a.addEventListener(o,h,!1)),m.add&&(m.add.call(a,l),l.handler.guid||(l.handler.guid=d.guid)),f?n.splice(n.delegateCount++,0,l):n.push(l),fa.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=qa.hasData(a)&&qa.get(a);if(q&&(i=q.events)){for(b=(b||\"\").match(ha)||[\"\"],j=b.length;j--;)if(h=Ba.exec(b[j])||[],n=p=h[1],o=(h[2]||\"\").split(\".\").sort(),n){for(l=fa.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp(\"(^|\\\\.)\"+o.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"),g=f=m.length;f--;)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&(\"**\"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||fa.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)fa.event.remove(a,n+b[j],c,d,!0);fa.isEmptyObject(i)&&(delete q.handle,qa.remove(a,\"events\"))}},trigger:function(c,d,e,f){var g,h,i,j,k,l,m,n=[e||T],o=da.call(c,\"type\")?c.type:c,p=da.call(c,\"namespace\")?c.namespace.split(\".\"):[];if(h=i=e=e||T,3!==e.nodeType&&8!==e.nodeType&&!Aa.test(o+fa.event.triggered)&&(o.indexOf(\".\")>=0&&(p=o.split(\".\"),o=p.shift(),p.sort()),k=o.indexOf(\":\")<0&&\"on\"+o,c=c[fa.expando]?c:new fa.Event(o,\"object\"==typeof c&&c),c.isTrigger=f?2:3,c.namespace=p.join(\".\"),c.namespace_re=c.namespace?new RegExp(\"(^|\\\\.)\"+p.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"):null,c.result=b,c.target||(c.target=e),d=null==d?[c]:fa.makeArray(d,[c]),m=fa.event.special[o]||{},f||!m.trigger||m.trigger.apply(e,d)!==!1)){if(!f&&!m.noBubble&&!fa.isWindow(e)){for(j=m.delegateType||o,Aa.test(j+o)||(h=h.parentNode);h;h=h.parentNode)n.push(h),i=h;i===(e.ownerDocument||T)&&n.push(i.defaultView||i.parentWindow||a)}for(g=0;(h=n[g++])&&!c.isPropagationStopped();)c.type=g>1?j:m.bindType||o,l=(qa.get(h,\"events\")||{})[c.type]&&qa.get(h,\"handle\"),l&&l.apply(h,d),l=k&&h[k],l&&fa.acceptData(h)&&l.apply&&l.apply(h,d)===!1&&c.preventDefault();return c.type=o,f||c.isDefaultPrevented()||m._default&&m._default.apply(n.pop(),d)!==!1||!fa.acceptData(e)||k&&fa.isFunction(e[o])&&!fa.isWindow(e)&&(i=e[k],i&&(e[k]=null),fa.event.triggered=o,e[o](),fa.event.triggered=b,i&&(e[k]=i)),c.result}},dispatch:function(a){a=fa.event.fix(a);var c,d,e,f,g,h=[],i=aa.call(arguments),j=(qa.get(this,\"events\")||{})[a.type]||[],k=fa.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){for(h=fa.event.handlers.call(this,a,j),c=0;(f=h[c++])&&!a.isPropagationStopped();)for(a.currentTarget=f.elem,d=0;(g=f.handlers[d++])&&!a.isImmediatePropagationStopped();)(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((fa.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),e!==b&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()));return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,c){var d,e,f,g,h=[],i=c.delegateCount,j=a.target;if(i&&j.nodeType&&(!a.button||\"click\"!==a.type))for(;j!==this;j=j.parentNode||this)if(j.disabled!==!0||\"click\"!==a.type){for(e=[],d=0;i>d;d++)g=c[d],f=g.selector+\" \",e[f]===b&&(e[f]=g.needsContext?fa(f,this).index(j)>=0:fa.find(f,this,null,[j]).length),e[f]&&e.push(g);e.length&&h.push({elem:j,handlers:e})}return i<c.length&&h.push({elem:this,handlers:c.slice(i)}),h},props:\"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),fixHooks:{},keyHooks:{props:\"char charCode key keyCode\".split(\" \"),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:\"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),filter:function(a,c){var d,e,f,g=c.button;return null==a.pageX&&null!=c.clientX&&(d=a.target.ownerDocument||T,e=d.documentElement,f=d.body,a.pageX=c.clientX+(e&&e.scrollLeft||f&&f.scrollLeft||0)-(e&&e.clientLeft||f&&f.clientLeft||0),a.pageY=c.clientY+(e&&e.scrollTop||f&&f.scrollTop||0)-(e&&e.clientTop||f&&f.clientTop||0)),a.which||g===b||(a.which=1&g?1:2&g?3:4&g?2:0),a}},fix:function(a){if(a[fa.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];for(g||(this.fixHooks[e]=g=za.test(e)?this.mouseHooks:ya.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new fa.Event(f),b=d.length;b--;)c=d[b],a[c]=f[c];return a.target||(a.target=T),3===a.target.nodeType&&(a.target=a.target.parentNode),g.filter?g.filter(a,f):a},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==i()&&this.focus?(this.focus(),!1):void 0},delegateType:\"focusin\"},blur:{trigger:function(){return this===i()&&this.blur?(this.blur(),!1):void 0},delegateType:\"focusout\"},click:{trigger:function(){return\"checkbox\"===this.type&&this.click&&fa.nodeName(this,\"input\")?(this.click(),!1):void 0},_default:function(a){return fa.nodeName(a.target,\"a\")}},beforeunload:{postDispatch:function(a){a.result!==b&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=fa.extend(new fa.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?fa.event.trigger(e,null,b):fa.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},fa.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)},fa.Event=function(a,b){return this instanceof fa.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.getPreventDefault&&a.getPreventDefault()?g:h):this.type=a,b&&fa.extend(this,b),this.timeStamp=a&&a.timeStamp||fa.now(),void(this[fa.expando]=!0)):new fa.Event(a,b)},fa.Event.prototype={isDefaultPrevented:h,isPropagationStopped:h,isImmediatePropagationStopped:h,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=g,a&&a.preventDefault&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=g,a&&a.stopPropagation&&a.stopPropagation()},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=g,this.stopPropagation()}},fa.each({mouseenter:\"mouseover\",mouseleave:\"mouseout\"},function(a,b){fa.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!fa.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),fa.support.focusinBubbles||fa.each({focus:\"focusin\",blur:\"focusout\"},function(a,b){var c=0,d=function(a){fa.event.simulate(b,a.target,fa.event.fix(a),!0)};fa.event.special[b]={setup:function(){0===c++&&T.addEventListener(a,d,!0)},teardown:function(){0===--c&&T.removeEventListener(a,d,!0)}}}),fa.fn.extend({on:function(a,c,d,e,f){var g,i;if(\"object\"==typeof a){\"string\"!=typeof c&&(d=d||c,c=b);for(i in a)this.on(i,c,d,a[i],f);return this}if(null==d&&null==e?(e=c,d=c=b):null==e&&(\"string\"==typeof c?(e=d,d=b):(e=d,d=c,c=b)),e===!1)e=h;else if(!e)return this;return 1===f&&(g=e,e=function(a){return fa().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=fa.guid++)),this.each(function(){fa.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,c,d){var e,f;if(a&&a.preventDefault&&a.handleObj)return e=a.handleObj,fa(a.delegateTarget).off(e.namespace?e.origType+\".\"+e.namespace:e.origType,e.selector,e.handler),this;if(\"object\"==typeof a){for(f in a)this.off(f,c,a[f]);return this}return(c===!1||\"function\"==typeof c)&&(d=c,c=b),d===!1&&(d=h),this.each(function(){fa.event.remove(this,a,d,c)})},trigger:function(a,b){return this.each(function(){fa.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?fa.event.trigger(a,b,c,!0):void 0}});var Ca=/^.[^:#\\[\\.,]*$/,Da=/^(?:parents|prev(?:Until|All))/,Ea=fa.expr.match.needsContext,Fa={children:!0,contents:!0,next:!0,prev:!0};fa.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if(\"string\"!=typeof a)return this.pushStack(fa(a).filter(function(){for(b=0;e>b;b++)if(fa.contains(d[b],this))return!0}));for(b=0;e>b;b++)fa.find(a,d[b],c);return c=this.pushStack(e>1?fa.unique(c):c),c.selector=this.selector?this.selector+\" \"+a:a,c},has:function(a){var b=fa(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(fa.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(k(this,a||[],!0))},filter:function(a){return this.pushStack(k(this,a||[],!1))},is:function(a){return!!k(this,\"string\"==typeof a&&Ea.test(a)?fa(a):a||[],!1).length},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=Ea.test(a)||\"string\"!=typeof a?fa(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&fa.find.matchesSelector(c,a))){c=f.push(c);break}return this.pushStack(f.length>1?fa.unique(f):f)},index:function(a){return a?\"string\"==typeof a?ba.call(fa(a),this[0]):ba.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){var c=\"string\"==typeof a?fa(a,b):fa.makeArray(a&&a.nodeType?[a]:a),d=fa.merge(this.get(),c);return this.pushStack(fa.unique(d))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}}),fa.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return fa.dir(a,\"parentNode\")},parentsUntil:function(a,b,c){return fa.dir(a,\"parentNode\",c)},next:function(a){return j(a,\"nextSibling\")},prev:function(a){return j(a,\"previousSibling\")},nextAll:function(a){return fa.dir(a,\"nextSibling\")},prevAll:function(a){return fa.dir(a,\"previousSibling\")},nextUntil:function(a,b,c){return fa.dir(a,\"nextSibling\",c)},prevUntil:function(a,b,c){return fa.dir(a,\"previousSibling\",c)},siblings:function(a){return fa.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return fa.sibling(a.firstChild)},contents:function(a){return a.contentDocument||fa.merge([],a.childNodes)}},function(a,b){fa.fn[a]=function(c,d){var e=fa.map(this,b,c);return\"Until\"!==a.slice(-5)&&(d=c),d&&\"string\"==typeof d&&(e=fa.filter(d,e)),this.length>1&&(Fa[a]||fa.unique(e),Da.test(a)&&e.reverse()),this.pushStack(e)}}),fa.extend({filter:function(a,b,c){var d=b[0];return c&&(a=\":not(\"+a+\")\"),1===b.length&&1===d.nodeType?fa.find.matchesSelector(d,a)?[d]:[]:fa.find.matches(a,fa.grep(b,function(a){return 1===a.nodeType}))},dir:function(a,c,d){for(var e=[],f=d!==b;(a=a[c])&&9!==a.nodeType;)if(1===a.nodeType){if(f&&fa(a).is(d))break;e.push(a)}return e},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}});var Ga=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,Ha=/<([\\w:]+)/,Ia=/<|&#?\\w+;/,Ja=/<(?:script|style|link)/i,Ka=/^(?:checkbox|radio)$/i,La=/checked\\s*(?:[^=]|=\\s*.checked.)/i,Ma=/^$|\\/(?:java|ecma)script/i,Na=/^true\\/(.*)/,Oa=/^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g,Pa={option:[1,\"<select multiple='multiple'>\",\"</select>\"],thead:[1,\"<table>\",\"</table>\"],col:[2,\"<table><colgroup>\",\"</colgroup></table>\"],tr:[2,\"<table><tbody>\",\"</tbody></table>\"],td:[3,\"<table><tbody><tr>\",\"</tr></tbody></table>\"],_default:[0,\"\",\"\"]};Pa.optgroup=Pa.option,Pa.tbody=Pa.tfoot=Pa.colgroup=Pa.caption=Pa.thead,Pa.th=Pa.td,fa.fn.extend({text:function(a){return fa.access(this,function(a){return a===b?fa.text(this):this.empty().append((this[0]&&this[0].ownerDocument||T).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=l(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=l(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?fa.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||fa.cleanData(q(c)),c.parentNode&&(b&&fa.contains(c.ownerDocument,c)&&o(q(c,\"script\")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(fa.cleanData(q(a,!1)),a.textContent=\"\");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return fa.clone(this,a,b)})},html:function(a){return fa.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b&&1===c.nodeType)return c.innerHTML;if(\"string\"==typeof a&&!Ja.test(a)&&!Pa[(Ha.exec(a)||[\"\",\"\"])[1].toLowerCase()]){a=a.replace(Ga,\"<$1></$2>\");try{for(;e>d;d++)c=this[d]||{},1===c.nodeType&&(fa.cleanData(q(c,!1)),c.innerHTML=a);c=0}catch(f){}}c&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=fa.map(this,function(a){return[a.nextSibling,a.parentNode]}),b=0;return this.domManip(arguments,function(c){var d=a[b++],e=a[b++];e&&(d&&d.parentNode!==e&&(d=this.nextSibling),fa(this).remove(),e.insertBefore(c,d))},!0),b?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b,c){a=$.apply([],a);var d,e,f,g,h,i,j=0,k=this.length,l=this,o=k-1,p=a[0],r=fa.isFunction(p);if(r||!(1>=k||\"string\"!=typeof p||fa.support.checkClone)&&La.test(p))return this.each(function(d){var e=l.eq(d);r&&(a[0]=p.call(this,d,e.html())),e.domManip(a,b,c)});if(k&&(d=fa.buildFragment(a,this[0].ownerDocument,!1,!c&&this),e=d.firstChild,1===d.childNodes.length&&(d=e),e)){for(f=fa.map(q(d,\"script\"),m),g=f.length;k>j;j++)h=d,j!==o&&(h=fa.clone(h,!0,!0),g&&fa.merge(f,q(h,\"script\"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,fa.map(f,n),j=0;g>j;j++)h=f[j],Ma.test(h.type||\"\")&&!qa.access(h,\"globalEval\")&&fa.contains(i,h)&&(h.src?fa._evalUrl(h.src):fa.globalEval(h.textContent.replace(Oa,\"\")))}return this}}),fa.each({appendTo:\"append\",prependTo:\"prepend\",insertBefore:\"before\",insertAfter:\"after\",replaceAll:\"replaceWith\"},function(a,b){fa.fn[a]=function(a){for(var c,d=[],e=fa(a),f=e.length-1,g=0;f>=g;g++)c=g===f?this:this.clone(!0),fa(e[g])[b](c),_.apply(d,c.get());return this.pushStack(d)}}),fa.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=fa.contains(a.ownerDocument,a);if(!(fa.support.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||fa.isXMLDoc(a)))for(g=q(h),f=q(a),d=0,e=f.length;e>d;d++)r(f[d],g[d]);if(b)if(c)for(f=f||q(a),g=g||q(h),d=0,e=f.length;e>d;d++)p(f[d],g[d]);else p(a,h);return g=q(h,\"script\"),g.length>0&&o(g,!i&&q(a,\"script\")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=0,l=a.length,m=b.createDocumentFragment(),n=[];l>k;k++)if(e=a[k],e||0===e)if(\"object\"===fa.type(e))fa.merge(n,e.nodeType?[e]:e);else if(Ia.test(e)){for(f=f||m.appendChild(b.createElement(\"div\")),g=(Ha.exec(e)||[\"\",\"\"])[1].toLowerCase(),h=Pa[g]||Pa._default,f.innerHTML=h[1]+e.replace(Ga,\"<$1></$2>\")+h[2],j=h[0];j--;)f=f.lastChild;fa.merge(n,f.childNodes),f=m.firstChild,f.textContent=\"\"}else n.push(b.createTextNode(e));for(m.textContent=\"\",k=0;e=n[k++];)if((!d||-1===fa.inArray(e,d))&&(i=fa.contains(e.ownerDocument,e),f=q(m.appendChild(e),\"script\"),i&&o(f),c))for(j=0;e=f[j++];)Ma.test(e.type||\"\")&&c.push(e);return m},cleanData:function(a){for(var c,d,f,g,h,i,j=fa.event.special,k=0;(d=a[k])!==b;k++){if(e.accepts(d)&&(h=d[qa.expando],h&&(c=qa.cache[h]))){if(f=Object.keys(c.events||{}),f.length)for(i=0;(g=f[i])!==b;i++)j[g]?fa.event.remove(d,g):fa.removeEvent(d,g,c.handle);qa.cache[h]&&delete qa.cache[h]}delete pa.cache[d[pa.expando]]}},_evalUrl:function(a){return fa.ajax({url:a,type:\"GET\",dataType:\"script\",async:!1,global:!1,\"throws\":!0})}}),fa.fn.extend({wrapAll:function(a){var b;return fa.isFunction(a)?this.each(function(b){fa(this).wrapAll(a.call(this,b))}):(this[0]&&(b=fa(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){for(var a=this;a.firstElementChild;)a=a.firstElementChild;return a}).append(this)),this)},wrapInner:function(a){return fa.isFunction(a)?this.each(function(b){fa(this).wrapInner(a.call(this,b))}):this.each(function(){var b=fa(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=fa.isFunction(a);return this.each(function(c){fa(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){fa.nodeName(this,\"body\")||fa(this).replaceWith(this.childNodes)}).end()}});var Qa,Ra,Sa=/^(none|table(?!-c[ea]).+)/,Ta=/^margin/,Ua=new RegExp(\"^(\"+ga+\")(.*)$\",\"i\"),Va=new RegExp(\"^(\"+ga+\")(?!px)[a-z%]+$\",\"i\"),Wa=new RegExp(\"^([+-])=(\"+ga+\")\",\"i\"),Xa={BODY:\"block\"},Ya={position:\"absolute\",visibility:\"hidden\",display:\"block\"},Za={letterSpacing:0,fontWeight:400},$a=[\"Top\",\"Right\",\"Bottom\",\"Left\"],_a=[\"Webkit\",\"O\",\"Moz\",\"ms\"];\nfa.fn.extend({css:function(a,c){return fa.access(this,function(a,c,d){var e,f,g={},h=0;if(fa.isArray(c)){for(e=u(a),f=c.length;f>h;h++)g[c[h]]=fa.css(a,c[h],!1,e);return g}return d!==b?fa.style(a,c,d):fa.css(a,c)},a,c,arguments.length>1)},show:function(){return v(this,!0)},hide:function(){return v(this)},toggle:function(a){return\"boolean\"==typeof a?a?this.show():this.hide():this.each(function(){t(this)?fa(this).show():fa(this).hide()})}}),fa.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Qa(a,\"opacity\");return\"\"===c?\"1\":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{\"float\":\"cssFloat\"},style:function(a,c,d,e){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var f,g,h,i=fa.camelCase(c),j=a.style;return c=fa.cssProps[i]||(fa.cssProps[i]=s(j,i)),h=fa.cssHooks[c]||fa.cssHooks[i],d===b?h&&\"get\"in h&&(f=h.get(a,!1,e))!==b?f:j[c]:(g=typeof d,\"string\"===g&&(f=Wa.exec(d))&&(d=(f[1]+1)*f[2]+parseFloat(fa.css(a,c)),g=\"number\"),null==d||\"number\"===g&&isNaN(d)||(\"number\"!==g||fa.cssNumber[i]||(d+=\"px\"),fa.support.clearCloneStyle||\"\"!==d||0!==c.indexOf(\"background\")||(j[c]=\"inherit\"),h&&\"set\"in h&&(d=h.set(a,d,e))===b||(j[c]=d)),void 0)}},css:function(a,c,d,e){var f,g,h,i=fa.camelCase(c);return c=fa.cssProps[i]||(fa.cssProps[i]=s(a.style,i)),h=fa.cssHooks[c]||fa.cssHooks[i],h&&\"get\"in h&&(f=h.get(a,!0,d)),f===b&&(f=Qa(a,c,e)),\"normal\"===f&&c in Za&&(f=Za[c]),\"\"===d||d?(g=parseFloat(f),d===!0||fa.isNumeric(g)?g||0:f):f}}),Qa=function(a,c,d){var e,f,g,h=d||u(a),i=h?h.getPropertyValue(c)||h[c]:b,j=a.style;return h&&(\"\"!==i||fa.contains(a.ownerDocument,a)||(i=fa.style(a,c)),Va.test(i)&&Ta.test(c)&&(e=j.width,f=j.minWidth,g=j.maxWidth,j.minWidth=j.maxWidth=j.width=i,i=h.width,j.width=e,j.minWidth=f,j.maxWidth=g)),i},fa.each([\"height\",\"width\"],function(a,b){fa.cssHooks[b]={get:function(a,c,d){return c?0===a.offsetWidth&&Sa.test(fa.css(a,\"display\"))?fa.swap(a,Ya,function(){return y(a,b,d)}):y(a,b,d):void 0},set:function(a,c,d){var e=d&&u(a);return w(a,c,d?x(a,b,d,fa.support.boxSizing&&\"border-box\"===fa.css(a,\"boxSizing\",!1,e),e):0)}}}),fa(function(){fa.support.reliableMarginRight||(fa.cssHooks.marginRight={get:function(a,b){return b?fa.swap(a,{display:\"inline-block\"},Qa,[a,\"marginRight\"]):void 0}}),!fa.support.pixelPosition&&fa.fn.position&&fa.each([\"top\",\"left\"],function(a,b){fa.cssHooks[b]={get:function(a,c){return c?(c=Qa(a,b),Va.test(c)?fa(a).position()[b]+\"px\":c):void 0}}})}),fa.expr&&fa.expr.filters&&(fa.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0},fa.expr.filters.visible=function(a){return!fa.expr.filters.hidden(a)}),fa.each({margin:\"\",padding:\"\",border:\"Width\"},function(a,b){fa.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f=\"string\"==typeof c?c.split(\" \"):[c];4>d;d++)e[a+$a[d]+b]=f[d]||f[d-2]||f[0];return e}},Ta.test(a)||(fa.cssHooks[a+b].set=w)});var ab=/%20/g,bb=/\\[\\]$/,cb=/\\r?\\n/g,db=/^(?:submit|button|image|reset|file)$/i,eb=/^(?:input|select|textarea|keygen)/i;fa.fn.extend({serialize:function(){return fa.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=fa.prop(this,\"elements\");return a?fa.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!fa(this).is(\":disabled\")&&eb.test(this.nodeName)&&!db.test(a)&&(this.checked||!Ka.test(a))}).map(function(a,b){var c=fa(this).val();return null==c?null:fa.isArray(c)?fa.map(c,function(a){return{name:b.name,value:a.replace(cb,\"\\r\\n\")}}):{name:b.name,value:c.replace(cb,\"\\r\\n\")}}).get()}}),fa.param=function(a,c){var d,e=[],f=function(a,b){b=fa.isFunction(b)?b():null==b?\"\":b,e[e.length]=encodeURIComponent(a)+\"=\"+encodeURIComponent(b)};if(c===b&&(c=fa.ajaxSettings&&fa.ajaxSettings.traditional),fa.isArray(a)||a.jquery&&!fa.isPlainObject(a))fa.each(a,function(){f(this.name,this.value)});else for(d in a)B(d,a[d],c,f);return e.join(\"&\").replace(ab,\"+\")},fa.each(\"blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu\".split(\" \"),function(a,b){fa.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),fa.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,\"**\"):this.off(b,a||\"**\",c)}});var fb,gb,hb=fa.now(),ib=/\\?/,jb=/#.*$/,kb=/([?&])_=[^&]*/,lb=/^(.*?):[ \\t]*([^\\r\\n]*)$/gm,mb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,nb=/^(?:GET|HEAD)$/,ob=/^\\/\\//,pb=/^([\\w.+-]+:)(?:\\/\\/([^\\/?#:]*)(?::(\\d+)|)|)/,qb=fa.fn.load,rb={},sb={},tb=\"*/\".concat(\"*\");try{gb=S.href}catch(ub){gb=T.createElement(\"a\"),gb.href=\"\",gb=gb.href}fb=pb.exec(gb.toLowerCase())||[],fa.fn.load=function(a,c,d){if(\"string\"!=typeof a&&qb)return qb.apply(this,arguments);var e,f,g,h=this,i=a.indexOf(\" \");return i>=0&&(e=a.slice(i),a=a.slice(0,i)),fa.isFunction(c)?(d=c,c=b):c&&\"object\"==typeof c&&(f=\"POST\"),h.length>0&&fa.ajax({url:a,type:f,dataType:\"html\",data:c}).done(function(a){g=arguments,h.html(e?fa(\"<div>\").append(fa.parseHTML(a)).find(e):a)}).complete(d&&function(a,b){h.each(d,g||[a.responseText,b,a])}),this},fa.each([\"ajaxStart\",\"ajaxStop\",\"ajaxComplete\",\"ajaxError\",\"ajaxSuccess\",\"ajaxSend\"],function(a,b){fa.fn[b]=function(a){return this.on(b,a)}}),fa.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:gb,type:\"GET\",isLocal:mb.test(fb[1]),global:!0,processData:!0,async:!0,contentType:\"application/x-www-form-urlencoded; charset=UTF-8\",accepts:{\"*\":tb,text:\"text/plain\",html:\"text/html\",xml:\"application/xml, text/xml\",json:\"application/json, text/javascript\"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:\"responseXML\",text:\"responseText\",json:\"responseJSON\"},converters:{\"* text\":String,\"text html\":!0,\"text json\":fa.parseJSON,\"text xml\":fa.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?E(E(a,fa.ajaxSettings),b):E(fa.ajaxSettings,a)},ajaxPrefilter:C(rb),ajaxTransport:C(sb),ajax:function(a,c){function d(a,c,d,h){var j,l,s,t,v,x=c;2!==u&&(u=2,i&&clearTimeout(i),e=b,g=h||\"\",w.readyState=a>0?4:0,j=a>=200&&300>a||304===a,d&&(t=F(m,w,d)),t=G(m,t,w,j),j?(m.ifModified&&(v=w.getResponseHeader(\"Last-Modified\"),v&&(fa.lastModified[f]=v),v=w.getResponseHeader(\"etag\"),v&&(fa.etag[f]=v)),204===a||\"HEAD\"===m.type?x=\"nocontent\":304===a?x=\"notmodified\":(x=t.state,l=t.data,s=t.error,j=!s)):(s=x,(a||!x)&&(x=\"error\",0>a&&(a=0))),w.status=a,w.statusText=(c||x)+\"\",j?p.resolveWith(n,[l,x,w]):p.rejectWith(n,[w,x,s]),w.statusCode(r),r=b,k&&o.trigger(j?\"ajaxSuccess\":\"ajaxError\",[w,m,j?l:s]),q.fireWith(n,[w,x]),k&&(o.trigger(\"ajaxComplete\",[w,m]),--fa.active||fa.event.trigger(\"ajaxStop\")))}\"object\"==typeof a&&(c=a,a=b),c=c||{};var e,f,g,h,i,j,k,l,m=fa.ajaxSetup({},c),n=m.context||m,o=m.context&&(n.nodeType||n.jquery)?fa(n):fa.event,p=fa.Deferred(),q=fa.Callbacks(\"once memory\"),r=m.statusCode||{},s={},t={},u=0,v=\"canceled\",w={readyState:0,getResponseHeader:function(a){var b;if(2===u){if(!h)for(h={};b=lb.exec(g);)h[b[1].toLowerCase()]=b[2];b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===u?g:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return u||(a=t[c]=t[c]||a,s[a]=b),this},overrideMimeType:function(a){return u||(m.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>u)for(b in a)r[b]=[r[b],a[b]];else w.always(a[w.status]);return this},abort:function(a){var b=a||v;return e&&e.abort(b),d(0,b),this}};if(p.promise(w).complete=q.add,w.success=w.done,w.error=w.fail,m.url=((a||m.url||gb)+\"\").replace(jb,\"\").replace(ob,fb[1]+\"//\"),m.type=c.method||c.type||m.method||m.type,m.dataTypes=fa.trim(m.dataType||\"*\").toLowerCase().match(ha)||[\"\"],null==m.crossDomain&&(j=pb.exec(m.url.toLowerCase()),m.crossDomain=!(!j||j[1]===fb[1]&&j[2]===fb[2]&&(j[3]||(\"http:\"===j[1]?\"80\":\"443\"))===(fb[3]||(\"http:\"===fb[1]?\"80\":\"443\")))),m.data&&m.processData&&\"string\"!=typeof m.data&&(m.data=fa.param(m.data,m.traditional)),D(rb,m,c,w),2===u)return w;k=m.global,k&&0===fa.active++&&fa.event.trigger(\"ajaxStart\"),m.type=m.type.toUpperCase(),m.hasContent=!nb.test(m.type),f=m.url,m.hasContent||(m.data&&(f=m.url+=(ib.test(f)?\"&\":\"?\")+m.data,delete m.data),m.cache===!1&&(m.url=kb.test(f)?f.replace(kb,\"$1_=\"+hb++):f+(ib.test(f)?\"&\":\"?\")+\"_=\"+hb++)),m.ifModified&&(fa.lastModified[f]&&w.setRequestHeader(\"If-Modified-Since\",fa.lastModified[f]),fa.etag[f]&&w.setRequestHeader(\"If-None-Match\",fa.etag[f])),(m.data&&m.hasContent&&m.contentType!==!1||c.contentType)&&w.setRequestHeader(\"Content-Type\",m.contentType),w.setRequestHeader(\"Accept\",m.dataTypes[0]&&m.accepts[m.dataTypes[0]]?m.accepts[m.dataTypes[0]]+(\"*\"!==m.dataTypes[0]?\", \"+tb+\"; q=0.01\":\"\"):m.accepts[\"*\"]);for(l in m.headers)w.setRequestHeader(l,m.headers[l]);if(m.beforeSend&&(m.beforeSend.call(n,w,m)===!1||2===u))return w.abort();v=\"abort\";for(l in{success:1,error:1,complete:1})w[l](m[l]);if(e=D(sb,m,c,w)){w.readyState=1,k&&o.trigger(\"ajaxSend\",[w,m]),m.async&&m.timeout>0&&(i=setTimeout(function(){w.abort(\"timeout\")},m.timeout));try{u=1,e.send(s,d)}catch(x){if(!(2>u))throw x;d(-1,x)}}else d(-1,\"No Transport\");return w},getJSON:function(a,b,c){return fa.get(a,b,c,\"json\")},getScript:function(a,c){return fa.get(a,b,c,\"script\")}}),fa.each([\"get\",\"post\"],function(a,c){fa[c]=function(a,d,e,f){return fa.isFunction(d)&&(f=f||e,e=d,d=b),fa.ajax({url:a,type:c,dataType:f,data:d,success:e})}}),fa.ajaxSetup({accepts:{script:\"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"},contents:{script:/(?:java|ecma)script/},converters:{\"text script\":function(a){return fa.globalEval(a),a}}}),fa.ajaxPrefilter(\"script\",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type=\"GET\")}),fa.ajaxTransport(\"script\",function(a){if(a.crossDomain){var b,c;return{send:function(d,e){b=fa(\"<script>\").prop({async:!0,charset:a.scriptCharset,src:a.url}).on(\"load error\",c=function(a){b.remove(),c=null,a&&e(\"error\"===a.type?404:200,a.type)}),T.head.appendChild(b[0])},abort:function(){c&&c()}}}});var vb=[],wb=/(=)\\?(?=&|$)|\\?\\?/;fa.ajaxSetup({jsonp:\"callback\",jsonpCallback:function(){var a=vb.pop()||fa.expando+\"_\"+hb++;return this[a]=!0,a}}),fa.ajaxPrefilter(\"json jsonp\",function(c,d,e){var f,g,h,i=c.jsonp!==!1&&(wb.test(c.url)?\"url\":\"string\"==typeof c.data&&!(c.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&wb.test(c.data)&&\"data\");return i||\"jsonp\"===c.dataTypes[0]?(f=c.jsonpCallback=fa.isFunction(c.jsonpCallback)?c.jsonpCallback():c.jsonpCallback,i?c[i]=c[i].replace(wb,\"$1\"+f):c.jsonp!==!1&&(c.url+=(ib.test(c.url)?\"&\":\"?\")+c.jsonp+\"=\"+f),c.converters[\"script json\"]=function(){return h||fa.error(f+\" was not called\"),h[0]},c.dataTypes[0]=\"json\",g=a[f],a[f]=function(){h=arguments},e.always(function(){a[f]=g,c[f]&&(c.jsonpCallback=d.jsonpCallback,vb.push(f)),h&&fa.isFunction(g)&&g(h[0]),h=g=b}),\"script\"):void 0}),fa.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(a){}};var xb=fa.ajaxSettings.xhr(),yb={0:200,1223:204},zb=0,Ab={};a.ActiveXObject&&fa(a).on(\"unload\",function(){for(var a in Ab)Ab[a]();Ab=b}),fa.support.cors=!!xb&&\"withCredentials\"in xb,fa.support.ajax=xb=!!xb,fa.ajaxTransport(function(a){var c;return fa.support.cors||xb&&!a.crossDomain?{send:function(d,e){var f,g,h=a.xhr();if(h.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(f in a.xhrFields)h[f]=a.xhrFields[f];a.mimeType&&h.overrideMimeType&&h.overrideMimeType(a.mimeType),a.crossDomain||d[\"X-Requested-With\"]||(d[\"X-Requested-With\"]=\"XMLHttpRequest\");for(f in d)h.setRequestHeader(f,d[f]);c=function(a){return function(){c&&(delete Ab[g],c=h.onload=h.onerror=null,\"abort\"===a?h.abort():\"error\"===a?e(h.status||404,h.statusText):e(yb[h.status]||h.status,h.statusText,\"string\"==typeof h.responseText?{text:h.responseText}:b,h.getAllResponseHeaders()))}},h.onload=c(),h.onerror=c(\"error\"),c=Ab[g=zb++]=c(\"abort\"),h.send(a.hasContent&&a.data||null)},abort:function(){c&&c()}}:void 0});var Bb,Cb,Db=/^(?:toggle|show|hide)$/,Eb=new RegExp(\"^(?:([+-])=|)(\"+ga+\")([a-z%]*)$\",\"i\"),Fb=/queueHooks$/,Gb=[L],Hb={\"*\":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=Eb.exec(b),f=e&&e[3]||(fa.cssNumber[a]?\"\":\"px\"),g=(fa.cssNumber[a]||\"px\"!==f&&+d)&&Eb.exec(fa.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||\".5\",g/=h,fa.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};fa.Animation=fa.extend(J,{tweener:function(a,b){fa.isFunction(a)?(b=a,a=[\"*\"]):a=a.split(\" \");for(var c,d=0,e=a.length;e>d;d++)c=a[d],Hb[c]=Hb[c]||[],Hb[c].unshift(b)},prefilter:function(a,b){b?Gb.unshift(a):Gb.push(a)}}),fa.Tween=M,M.prototype={constructor:M,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||\"swing\",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(fa.cssNumber[c]?\"\":\"px\")},cur:function(){var a=M.propHooks[this.prop];return a&&a.get?a.get(this):M.propHooks._default.get(this)},run:function(a){var b,c=M.propHooks[this.prop];return this.options.duration?this.pos=b=fa.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):M.propHooks._default.set(this),this}},M.prototype.init.prototype=M.prototype,M.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=fa.css(a.elem,a.prop,\"\"),b&&\"auto\"!==b?b:0):a.elem[a.prop]},set:function(a){fa.fx.step[a.prop]?fa.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[fa.cssProps[a.prop]]||fa.cssHooks[a.prop])?fa.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},M.propHooks.scrollTop=M.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},fa.each([\"toggle\",\"show\",\"hide\"],function(a,b){var c=fa.fn[b];fa.fn[b]=function(a,d,e){return null==a||\"boolean\"==typeof a?c.apply(this,arguments):this.animate(N(b,!0),a,d,e)}}),fa.fn.extend({fadeTo:function(a,b,c,d){return this.filter(t).css(\"opacity\",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=fa.isEmptyObject(a),f=fa.speed(b,c,d),g=function(){var b=J(this,fa.extend({},a),f);(e||qa.get(this,\"finish\"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,c,d){var e=function(a){var b=a.stop;delete a.stop,b(d)};return\"string\"!=typeof a&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||\"fx\",[]),this.each(function(){var b=!0,c=null!=a&&a+\"queueHooks\",f=fa.timers,g=qa.get(this);if(c)g[c]&&g[c].stop&&e(g[c]);else for(c in g)g[c]&&g[c].stop&&Fb.test(c)&&e(g[c]);for(c=f.length;c--;)f[c].elem!==this||null!=a&&f[c].queue!==a||(f[c].anim.stop(d),b=!1,f.splice(c,1));(b||!d)&&fa.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||\"fx\"),this.each(function(){var b,c=qa.get(this),d=c[a+\"queue\"],e=c[a+\"queueHooks\"],f=fa.timers,g=d?d.length:0;for(c.finish=!0,fa.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),fa.each({slideDown:N(\"show\"),slideUp:N(\"hide\"),slideToggle:N(\"toggle\"),fadeIn:{opacity:\"show\"},fadeOut:{opacity:\"hide\"},fadeToggle:{opacity:\"toggle\"}},function(a,b){fa.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),fa.speed=function(a,b,c){var d=a&&\"object\"==typeof a?fa.extend({},a):{complete:c||!c&&b||fa.isFunction(a)&&a,duration:a,easing:c&&b||b&&!fa.isFunction(b)&&b};return d.duration=fa.fx.off?0:\"number\"==typeof d.duration?d.duration:d.duration in fa.fx.speeds?fa.fx.speeds[d.duration]:fa.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue=\"fx\"),d.old=d.complete,d.complete=function(){fa.isFunction(d.old)&&d.old.call(this),d.queue&&fa.dequeue(this,d.queue)},d},fa.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},fa.timers=[],fa.fx=M.prototype.init,fa.fx.tick=function(){var a,c=fa.timers,d=0;for(Bb=fa.now();d<c.length;d++)a=c[d],a()||c[d]!==a||c.splice(d--,1);c.length||fa.fx.stop(),Bb=b},fa.fx.timer=function(a){a()&&fa.timers.push(a)&&fa.fx.start()},fa.fx.interval=13,fa.fx.start=function(){Cb||(Cb=setInterval(fa.fx.tick,fa.fx.interval))},fa.fx.stop=function(){clearInterval(Cb),Cb=null},fa.fx.speeds={slow:600,fast:200,_default:400},fa.fx.step={},fa.expr&&fa.expr.filters&&(fa.expr.filters.animated=function(a){return fa.grep(fa.timers,function(b){return a===b.elem}).length}),fa.fn.offset=function(a){if(arguments.length)return a===b?this:this.each(function(b){fa.offset.setOffset(this,a,b)});var c,d,e=this[0],f={top:0,left:0},g=e&&e.ownerDocument;if(g)return c=g.documentElement,fa.contains(c,e)?(typeof e.getBoundingClientRect!==R&&(f=e.getBoundingClientRect()),d=O(g),{top:f.top+d.pageYOffset-c.clientTop,left:f.left+d.pageXOffset-c.clientLeft}):f},fa.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=fa.css(a,\"position\"),l=fa(a),m={};\"static\"===k&&(a.style.position=\"relative\"),h=l.offset(),f=fa.css(a,\"top\"),i=fa.css(a,\"left\"),j=(\"absolute\"===k||\"fixed\"===k)&&(f+i).indexOf(\"auto\")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),fa.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),\"using\"in b?b.using.call(a,m):l.css(m)}},fa.fn.extend({position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return\"fixed\"===fa.css(c,\"position\")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),fa.nodeName(a[0],\"html\")||(d=a.offset()),d.top+=fa.css(a[0],\"borderTopWidth\",!0),d.left+=fa.css(a[0],\"borderLeftWidth\",!0)),{top:b.top-d.top-fa.css(c,\"marginTop\",!0),left:b.left-d.left-fa.css(c,\"marginLeft\",!0)}}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||U;a&&!fa.nodeName(a,\"html\")&&\"static\"===fa.css(a,\"position\");)a=a.offsetParent;return a||U})}}),fa.each({scrollLeft:\"pageXOffset\",scrollTop:\"pageYOffset\"},function(c,d){var e=\"pageYOffset\"===d;fa.fn[c]=function(f){return fa.access(this,function(c,f,g){var h=O(c);return g===b?h?h[d]:c[f]:void(h?h.scrollTo(e?a.pageXOffset:g,e?g:a.pageYOffset):c[f]=g)},c,f,arguments.length,null)}}),fa.each({Height:\"height\",Width:\"width\"},function(a,c){fa.each({padding:\"inner\"+a,content:c,\"\":\"outer\"+a},function(d,e){fa.fn[e]=function(e,f){var g=arguments.length&&(d||\"boolean\"!=typeof e),h=d||(e===!0||f===!0?\"margin\":\"border\");return fa.access(this,function(c,d,e){var f;return fa.isWindow(c)?c.document.documentElement[\"client\"+a]:9===c.nodeType?(f=c.documentElement,Math.max(c.body[\"scroll\"+a],f[\"scroll\"+a],c.body[\"offset\"+a],f[\"offset\"+a],f[\"client\"+a])):e===b?fa.css(c,d,h):fa.style(c,d,e,h)},c,g?e:b,g,null)}})}),fa.fn.size=function(){return this.length},fa.fn.andSelf=fa.fn.addBack,\"object\"==typeof module&&module&&\"object\"==typeof module.exports?module.exports=fa:\"function\"==typeof define&&define.amd&&define(\"jquery\",[],function(){return fa}),\"object\"==typeof a&&\"object\"==typeof a.document&&(a.jQuery=a.$=fa)}(window);var requirejs,require,define;!function(global){function isFunction(a){return\"[object Function]\"===ostring.call(a)}function isArray(a){return\"[object Array]\"===ostring.call(a)}function each(a,b){if(a){var c;for(c=0;c<a.length&&(!a[c]||!b(a[c],c,a));c+=1);}}function eachReverse(a,b){if(a){var c;for(c=a.length-1;c>-1&&(!a[c]||!b(a[c],c,a));c-=1);}}function hasProp(a,b){return hasOwn.call(a,b)}function getOwn(a,b){return hasProp(a,b)&&a[b]}function eachProp(a,b){var c;for(c in a)if(hasProp(a,c)&&b(a[c],c))break}function mixin(a,b,c,d){return b&&eachProp(b,function(b,e){(c||!hasProp(a,e))&&(!d||\"object\"!=typeof b||!b||isArray(b)||isFunction(b)||b instanceof RegExp?a[e]=b:(a[e]||(a[e]={}),mixin(a[e],b,c,d)))}),a}function bind(a,b){return function(){return b.apply(a,arguments)}}function scripts(){return document.getElementsByTagName(\"script\")}function defaultOnError(a){throw a}function getGlobal(a){if(!a)return a;var b=global;return each(a.split(\".\"),function(a){b=b[a]}),b}function makeError(a,b,c,d){var e=new Error(b+\"\\nhttp://requirejs.org/docs/errors.html#\"+a);return e.requireType=a,e.requireModules=d,c&&(e.originalError=c),e}function newContext(a){function b(a){var b,c;for(b=0;b<a.length;b++)if(c=a[b],\".\"===c)a.splice(b,1),b-=1;else if(\"..\"===c){if(0===b||1===b&&\"..\"===a[2]||\"..\"===a[b-1])continue;b>0&&(a.splice(b-1,2),b-=2)}}function c(a,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q=c&&c.split(\"/\"),r=x.map,s=r&&r[\"*\"];if(a&&(a=a.split(\"/\"),k=a.length-1,x.nodeIdCompat&&jsSuffixRegExp.test(a[k])&&(a[k]=a[k].replace(jsSuffixRegExp,\"\")),\".\"===a[0].charAt(0)&&q&&(p=q.slice(0,q.length-1),a=p.concat(a)),b(a),a=a.join(\"/\")),d&&r&&(q||s)){g=a.split(\"/\");a:for(h=g.length;h>0;h-=1){if(j=g.slice(0,h).join(\"/\"),q)for(i=q.length;i>0;i-=1)if(f=getOwn(r,q.slice(0,i).join(\"/\")),f&&(f=getOwn(f,j))){l=f,m=h;break a}!n&&s&&getOwn(s,j)&&(n=getOwn(s,j),o=h)}!l&&n&&(l=n,m=o),l&&(g.splice(0,m,l),a=g.join(\"/\"))}return e=getOwn(x.pkgs,a),e?e:a}function d(a){isBrowser&&each(scripts(),function(b){return b.getAttribute(\"data-requiremodule\")===a&&b.getAttribute(\"data-requirecontext\")===u.contextName?(b.parentNode.removeChild(b),!0):void 0})}function e(a){var b=getOwn(x.paths,a);return b&&isArray(b)&&b.length>1?(b.shift(),u.require.undef(a),u.makeRequire(null,{skipMap:!0})([a]),!0):void 0}function f(a){var b,c=a?a.indexOf(\"!\"):-1;return c>-1&&(b=a.substring(0,c),a=a.substring(c+1,a.length)),[b,a]}function g(a,b,d,e){var g,h,i,j,k=null,l=b?b.name:null,m=a,n=!0,o=\"\";return a||(n=!1,a=\"_@r\"+(F+=1)),j=f(a),k=j[0],a=j[1],k&&(k=c(k,l,e),h=getOwn(C,k)),a&&(k?o=h&&h.normalize?h.normalize(a,function(a){return c(a,l,e)}):-1===a.indexOf(\"!\")?c(a,l,e):a:(o=c(a,l,e),j=f(o),k=j[0],o=j[1],d=!0,g=u.nameToUrl(o))),i=!k||h||d?\"\":\"_unnormalized\"+(G+=1),{prefix:k,name:o,parentMap:b,unnormalized:!!i,url:g,originalName:m,isDefine:n,id:(k?k+\"!\"+o:o)+i}}function h(a){var b=a.id,c=getOwn(y,b);return c||(c=y[b]=new u.Module(a)),c}function i(a,b,c){var d=a.id,e=getOwn(y,d);!hasProp(C,d)||e&&!e.defineEmitComplete?(e=h(a),e.error&&\"error\"===b?c(e.error):e.on(b,c)):\"defined\"===b&&c(C[d])}function j(a,b){var c=a.requireModules,d=!1;b?b(a):(each(c,function(b){var c=getOwn(y,b);c&&(c.error=a,c.events.error&&(d=!0,c.emit(\"error\",a)))}),d||req.onError(a))}function k(){globalDefQueue.length&&(each(globalDefQueue,function(a){var b=a[0];\"string\"==typeof b&&(u.defQueueMap[b]=!0),B.push(a)}),globalDefQueue=[])}function l(a){delete y[a],delete z[a]}function m(a,b,c){var d=a.map.id;a.error?a.emit(\"error\",a.error):(b[d]=!0,each(a.depMaps,function(d,e){var f=d.id,g=getOwn(y,f);!g||a.depMatched[e]||c[f]||(getOwn(b,f)?(a.defineDep(e,C[f]),a.check()):m(g,b,c))}),c[d]=!0)}function n(){var a,b,c=1e3*x.waitSeconds,f=c&&u.startTime+c<(new Date).getTime(),g=[],h=[],i=!1,k=!0;if(!s){if(s=!0,eachProp(z,function(a){var c=a.map,j=c.id;if(a.enabled&&(c.isDefine||h.push(a),!a.error))if(!a.inited&&f)e(j)?(b=!0,i=!0):(g.push(j),d(j));else if(!a.inited&&a.fetched&&c.isDefine&&(i=!0,!c.prefix))return k=!1}),f&&g.length)return a=makeError(\"timeout\",\"Load timeout for modules: \"+g,null,g),a.contextName=u.contextName,j(a);k&&each(h,function(a){m(a,{},{})}),f&&!b||!i||!isBrowser&&!isWebWorker||w||(w=setTimeout(function(){w=0,n()},50)),s=!1}}function o(a){hasProp(C,a[0])||h(g(a[0],null,!0)).init(a[1],a[2])}function p(a,b,c,d){a.detachEvent&&!isOpera?d&&a.detachEvent(d,b):a.removeEventListener(c,b,!1)}function q(a){var b=a.currentTarget||a.srcElement;return p(b,u.onScriptLoad,\"load\",\"onreadystatechange\"),p(b,u.onScriptError,\"error\"),{node:b,id:b&&b.getAttribute(\"data-requiremodule\")}}function r(){var a;for(k();B.length;){if(a=B.shift(),null===a[0])return j(makeError(\"mismatch\",\"Mismatched anonymous define() module: \"+a[a.length-1]));o(a)}u.defQueueMap={}}var s,t,u,v,w,x={waitSeconds:7,baseUrl:\"./\",paths:{},bundles:{},pkgs:{},shim:{},config:{}},y={},z={},A={},B=[],C={},D={},E={},F=1,G=1;return v={require:function(a){return a.require?a.require:a.require=u.makeRequire(a.map)},exports:function(a){return a.usingExports=!0,a.map.isDefine?a.exports?C[a.map.id]=a.exports:a.exports=C[a.map.id]={}:void 0},module:function(a){return a.module?a.module:a.module={id:a.map.id,uri:a.map.url,config:function(){return getOwn(x.config,a.map.id)||{}},exports:a.exports||(a.exports={})}}},t=function(a){this.events=getOwn(A,a.id)||{},this.map=a,this.shim=getOwn(x.shim,a.id),this.depExports=[],this.depMaps=[],this.depMatched=[],this.pluginMaps={},this.depCount=0},t.prototype={init:function(a,b,c,d){d=d||{},this.inited||(this.factory=b,c?this.on(\"error\",c):this.events.error&&(c=bind(this,function(a){this.emit(\"error\",a)})),this.depMaps=a&&a.slice(0),this.errback=c,this.inited=!0,this.ignore=d.ignore,d.enabled||this.enabled?this.enable():this.check())},defineDep:function(a,b){this.depMatched[a]||(this.depMatched[a]=!0,this.depCount-=1,this.depExports[a]=b)},fetch:function(){if(!this.fetched){this.fetched=!0,u.startTime=(new Date).getTime();var a=this.map;return this.shim?void u.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],bind(this,function(){return a.prefix?this.callPlugin():this.load()})):a.prefix?this.callPlugin():this.load()}},load:function(){var a=this.map.url;D[a]||(D[a]=!0,u.load(this.map.id,a))},check:function(){if(this.enabled&&!this.enabling){var a,b,c=this.map.id,d=this.depExports,e=this.exports,f=this.factory;if(this.inited){if(this.error)this.emit(\"error\",this.error);else if(!this.defining){if(this.defining=!0,this.depCount<1&&!this.defined){if(isFunction(f)){try{e=u.execCb(c,f,d,e)}catch(g){a=g}if(this.map.isDefine&&void 0===e&&(b=this.module,b?e=b.exports:this.usingExports&&(e=this.exports)),a){if(this.events.error&&this.map.isDefine||req.onError!==defaultOnError)return a.requireMap=this.map,a.requireModules=this.map.isDefine?[this.map.id]:null,a.requireType=this.map.isDefine?\"define\":\"require\",j(this.error=a);\"undefined\"!=typeof console&&console.error?console.error(a):req.onError(a)}}else e=f;if(this.exports=e,this.map.isDefine&&!this.ignore&&(C[c]=e,req.onResourceLoad)){var h=[];each(this.depMaps,function(a){h.push(a.normalizedMap||a)}),req.onResourceLoad(u,this.map,h)}l(c),this.defined=!0}this.defining=!1,this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit(\"defined\",this.exports),this.defineEmitComplete=!0)}}else hasProp(u.defQueueMap,c)||this.fetch()}},callPlugin:function(){var a=this.map,b=a.id,d=g(a.prefix);this.depMaps.push(d),i(d,\"defined\",bind(this,function(d){var e,f,k,m=getOwn(E,this.map.id),n=this.map.name,o=this.map.parentMap?this.map.parentMap.name:null,p=u.makeRequire(a.parentMap,{enableBuildCallback:!0});return this.map.unnormalized?(d.normalize&&(n=d.normalize(n,function(a){return c(a,o,!0)})||\"\"),f=g(a.prefix+\"!\"+n,this.map.parentMap),i(f,\"defined\",bind(this,function(a){this.map.normalizedMap=f,this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),k=getOwn(y,f.id),void(k&&(this.depMaps.push(f),this.events.error&&k.on(\"error\",bind(this,function(a){this.emit(\"error\",a)})),k.enable()))):m?(this.map.url=u.nameToUrl(m),void this.load()):(e=bind(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),e.error=bind(this,function(a){this.inited=!0,this.error=a,a.requireModules=[b],eachProp(y,function(a){0===a.map.id.indexOf(b+\"_unnormalized\")&&l(a.map.id)}),j(a)}),e.fromText=bind(this,function(c,d){var f=a.name,i=g(f),k=useInteractive;d&&(c=d),k&&(useInteractive=!1),h(i),hasProp(x.config,b)&&(x.config[f]=x.config[b]);try{req.exec(c)}catch(l){return j(makeError(\"fromtexteval\",\"fromText eval for \"+b+\" failed: \"+l,l,[b]))}k&&(useInteractive=!0),this.depMaps.push(i),u.completeLoad(f),p([f],e)}),void d.load(a.name,p,e,x))})),u.enable(d,this),this.pluginMaps[d.id]=d},enable:function(){z[this.map.id]=this,this.enabled=!0,this.enabling=!0,each(this.depMaps,bind(this,function(a,b){var c,d,e;if(\"string\"==typeof a){if(a=g(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap),this.depMaps[b]=a,e=getOwn(v,a.id))return void(this.depExports[b]=e(this));this.depCount+=1,i(a,\"defined\",bind(this,function(a){this.undefed||(this.defineDep(b,a),this.check())})),this.errback?i(a,\"error\",bind(this,this.errback)):this.events.error&&i(a,\"error\",bind(this,function(a){this.emit(\"error\",a)}))}c=a.id,d=y[c],hasProp(v,c)||!d||d.enabled||u.enable(a,this)})),eachProp(this.pluginMaps,bind(this,function(a){var b=getOwn(y,a.id);b&&!b.enabled&&u.enable(a,this)})),this.enabling=!1,this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]),c.push(b)},emit:function(a,b){each(this.events[a],function(a){a(b)}),\"error\"===a&&delete this.events[a]}},u={config:x,contextName:a,registry:y,defined:C,urlFetched:D,defQueue:B,defQueueMap:{},Module:t,makeModuleMap:g,nextTick:req.nextTick,onError:j,configure:function(a){a.baseUrl&&\"/\"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+=\"/\");var b=x.shim,c={paths:!0,bundles:!0,config:!0,map:!0};eachProp(a,function(a,b){c[b]?(x[b]||(x[b]={}),mixin(x[b],a,!0,!0)):x[b]=a}),a.bundles&&eachProp(a.bundles,function(a,b){each(a,function(a){a!==b&&(E[a]=b)})}),a.shim&&(eachProp(a.shim,function(a,c){isArray(a)&&(a={deps:a}),!a.exports&&!a.init||a.exportsFn||(a.exportsFn=u.makeShimExports(a)),b[c]=a}),x.shim=b),a.packages&&each(a.packages,function(a){var b,c;a=\"string\"==typeof a?{name:a}:a,c=a.name,b=a.location,b&&(x.paths[c]=a.location),x.pkgs[c]=a.name+\"/\"+(a.main||\"main\").replace(currDirRegExp,\"\").replace(jsSuffixRegExp,\"\")}),eachProp(y,function(a,b){a.inited||a.map.unnormalized||(a.map=g(b,null,!0))}),(a.deps||a.callback)&&u.require(a.deps||[],a.callback)},makeShimExports:function(a){function b(){var b;return a.init&&(b=a.init.apply(global,arguments)),b||a.exports&&getGlobal(a.exports)}return b},makeRequire:function(b,e){function f(c,d,i){var k,l,m;return e.enableBuildCallback&&d&&isFunction(d)&&(d.__requireJsBuild=!0),\"string\"==typeof c?isFunction(d)?j(makeError(\"requireargs\",\"Invalid require call\"),i):b&&hasProp(v,c)?v[c](y[b.id]):req.get?req.get(u,c,b,f):(l=g(c,b,!1,!0),k=l.id,hasProp(C,k)?C[k]:j(makeError(\"notloaded\",'Module name \"'+k+'\" has not been loaded yet for context: '+a+(b?\"\":\". Use require([])\")))):(r(),u.nextTick(function(){r(),m=h(g(null,b)),m.skipMap=e.skipMap,m.init(c,d,i,{enabled:!0}),n()}),f)}return e=e||{},mixin(f,{isBrowser:isBrowser,toUrl:function(a){var d,e=a.lastIndexOf(\".\"),f=a.split(\"/\")[0],g=\".\"===f||\"..\"===f;return-1!==e&&(!g||e>1)&&(d=a.substring(e,a.length),a=a.substring(0,e)),u.nameToUrl(c(a,b&&b.id,!0),d,!0)},defined:function(a){return hasProp(C,g(a,b,!1,!0).id)},specified:function(a){return a=g(a,b,!1,!0).id,hasProp(C,a)||hasProp(y,a)}}),b||(f.undef=function(a){k();var c=g(a,b,!0),e=getOwn(y,a);e.undefed=!0,d(a),delete C[a],delete D[c.url],delete A[a],eachReverse(B,function(b,c){b[0]===a&&B.splice(c,1)}),delete u.defQueueMap[a],e&&(e.events.defined&&(A[a]=e.events),l(a))}),f},enable:function(a){var b=getOwn(y,a.id);b&&h(a).enable()},completeLoad:function(a){var b,c,d,f=getOwn(x.shim,a)||{},g=f.exports;for(k();B.length;){if(c=B.shift(),null===c[0]){if(c[0]=a,b)break;b=!0}else c[0]===a&&(b=!0);o(c)}if(u.defQueueMap={},d=getOwn(y,a),!b&&!hasProp(C,a)&&d&&!d.inited){if(!(!x.enforceDefine||g&&getGlobal(g)))return e(a)?void 0:j(makeError(\"nodefine\",\"No define call for \"+a,null,[a]));o([a,f.deps||[],f.exportsFn])}n()},nameToUrl:function(a,b,c){var d,e,f,g,h,i,j,k=getOwn(x.pkgs,a);if(k&&(a=k),j=getOwn(E,a))return u.nameToUrl(j,b,c);if(req.jsExtRegExp.test(a))h=a+(b||\"\");else{for(d=x.paths,e=a.split(\"/\"),f=e.length;f>0;f-=1)if(g=e.slice(0,f).join(\"/\"),i=getOwn(d,g)){isArray(i)&&(i=i[0]),e.splice(0,f,i);break}h=e.join(\"/\"),h+=b||(/^data\\:|\\?/.test(h)||c?\"\":\".js\"),h=(\"/\"===h.charAt(0)||h.match(/^[\\w\\+\\.\\-]+:/)?\"\":x.baseUrl)+h;\n}return x.urlArgs?h+((-1===h.indexOf(\"?\")?\"?\":\"&\")+x.urlArgs):h},load:function(a,b){req.load(u,a,b)},execCb:function(a,b,c,d){return b.apply(d,c)},onScriptLoad:function(a){if(\"load\"===a.type||readyRegExp.test((a.currentTarget||a.srcElement).readyState)){interactiveScript=null;var b=q(a);u.completeLoad(b.id)}},onScriptError:function(a){var b=q(a);if(!e(b.id)){var c=[];return eachProp(y,function(a,d){0!==d.indexOf(\"_@r\")&&each(a.depMaps,function(a){return a.id===b.id&&c.push(d),!0})}),j(makeError(\"scripterror\",'Script error for \"'+b.id+(c.length?'\", needed by: '+c.join(\", \"):'\"'),a,[b.id]))}}},u.require=u.makeRequire(),u}function getInteractiveScript(){return interactiveScript&&\"interactive\"===interactiveScript.readyState?interactiveScript:(eachReverse(scripts(),function(a){return\"interactive\"===a.readyState?interactiveScript=a:void 0}),interactiveScript)}var req,s,head,baseElement,dataMain,src,interactiveScript,currentlyAddingScript,mainScript,subPath,version=\"2.1.22\",commentRegExp=/(\\/\\*([\\s\\S]*?)\\*\\/|([^:]|^)\\/\\/(.*)$)/gm,cjsRequireRegExp=/[^.]\\s*require\\s*\\(\\s*[\"']([^'\"\\s]+)[\"']\\s*\\)/g,jsSuffixRegExp=/\\.js$/,currDirRegExp=/^\\.\\//,op=Object.prototype,ostring=op.toString,hasOwn=op.hasOwnProperty,ap=Array.prototype,isBrowser=!(\"undefined\"==typeof window||\"undefined\"==typeof navigator||!window.document),isWebWorker=!isBrowser&&\"undefined\"!=typeof importScripts,readyRegExp=isBrowser&&\"PLAYSTATION 3\"===navigator.platform?/^complete$/:/^(complete|loaded)$/,defContextName=\"_\",isOpera=\"undefined\"!=typeof opera&&\"[object Opera]\"===opera.toString(),contexts={},cfg={},globalDefQueue=[],useInteractive=!1;if(\"undefined\"==typeof define){if(\"undefined\"!=typeof requirejs){if(isFunction(requirejs))return;cfg=requirejs,requirejs=void 0}\"undefined\"==typeof require||isFunction(require)||(cfg=require,require=void 0),req=requirejs=function(a,b,c,d){var e,f,g=defContextName;return isArray(a)||\"string\"==typeof a||(f=a,isArray(b)?(a=b,b=c,c=d):a=[]),f&&f.context&&(g=f.context),e=getOwn(contexts,g),e||(e=contexts[g]=req.s.newContext(g)),f&&e.configure(f),e.require(a,b,c)},req.config=function(a){return req(a)},req.nextTick=\"undefined\"!=typeof setTimeout?function(a){setTimeout(a,4)}:function(a){a()},require||(require=req),req.version=version,req.jsExtRegExp=/^\\/|:|\\?|\\.js$/,req.isBrowser=isBrowser,s=req.s={contexts:contexts,newContext:newContext},req({}),each([\"toUrl\",\"undef\",\"defined\",\"specified\"],function(a){req[a]=function(){var b=contexts[defContextName];return b.require[a].apply(b,arguments)}}),isBrowser&&(head=s.head=document.getElementsByTagName(\"head\")[0],baseElement=document.getElementsByTagName(\"base\")[0],baseElement&&(head=s.head=baseElement.parentNode)),req.onError=defaultOnError,req.createNode=function(a,b,c){var d=a.xhtml?document.createElementNS(\"http://www.w3.org/1999/xhtml\",\"html:script\"):document.createElement(\"script\");return d.type=a.scriptType||\"text/javascript\",d.charset=\"utf-8\",d.async=!0,d},req.load=function(a,b,c){var d,e=a&&a.config||{};if(isBrowser)return d=req.createNode(e,b,c),e.onNodeCreated&&e.onNodeCreated(d,e,b,c),d.setAttribute(\"data-requirecontext\",a.contextName),d.setAttribute(\"data-requiremodule\",b),!d.attachEvent||d.attachEvent.toString&&d.attachEvent.toString().indexOf(\"[native code\")<0||isOpera?(d.addEventListener(\"load\",a.onScriptLoad,!1),d.addEventListener(\"error\",a.onScriptError,!1)):(useInteractive=!0,d.attachEvent(\"onreadystatechange\",a.onScriptLoad)),d.src=c,currentlyAddingScript=d,baseElement?head.insertBefore(d,baseElement):head.appendChild(d),currentlyAddingScript=null,d;if(isWebWorker)try{importScripts(c),a.completeLoad(b)}catch(f){a.onError(makeError(\"importscripts\",\"importScripts failed for \"+b+\" at \"+c,f,[b]))}},isBrowser&&!cfg.skipDataMain&&eachReverse(scripts(),function(a){return head||(head=a.parentNode),dataMain=a.getAttribute(\"data-main\"),dataMain?(mainScript=dataMain,cfg.baseUrl||(src=mainScript.split(\"/\"),mainScript=src.pop(),subPath=src.length?src.join(\"/\")+\"/\":\"./\",cfg.baseUrl=subPath),mainScript=mainScript.replace(jsSuffixRegExp,\"\"),req.jsExtRegExp.test(mainScript)&&(mainScript=dataMain),cfg.deps=cfg.deps?cfg.deps.concat(mainScript):[mainScript],!0):void 0}),define=function(a,b,c){var d,e;\"string\"!=typeof a&&(c=b,b=a,a=null),isArray(b)||(c=b,b=null),!b&&isFunction(c)&&(b=[],c.length&&(c.toString().replace(commentRegExp,\"\").replace(cjsRequireRegExp,function(a,c){b.push(c)}),b=(1===c.length?[\"require\"]:[\"require\",\"exports\",\"module\"]).concat(b))),useInteractive&&(d=currentlyAddingScript||getInteractiveScript(),d&&(a||(a=d.getAttribute(\"data-requiremodule\")),e=contexts[d.getAttribute(\"data-requirecontext\")])),e?(e.defQueue.push([a,b,c]),e.defQueueMap[a]=!0):globalDefQueue.push([a,b,c])},define.amd={jQuery:!0},req.exec=function(text){return eval(text)},req(cfg)}}(this),require.config({paths:{cookie:\"lib/plugin/jquery.cookie\",ga:\"lib/ga\",uuid:\"lib/uuid\",user:\"lib/user\",tmpl:\"lib/tmpl\",anonymous:\"lib/anonymous\",visit_api:\"data/visit\"},shim:{}});"
  },
  {
    "path": "client/app/src/main/assets/guokr_master.css",
    "content": "html{display:block}head{display:none}title{display:none}style{display:none}body{display:block}article,aside,footer,header,hgroup,nav,section{display:block}p{display:block;-webkit-margin-before:1em;-webkit-margin-after:1em;-webkit-margin-start:0;-webkit-margin-end:0;color:#4e4e4e}p.editors-note{background-color:#eee;border:1px solid #ccc;font-size:14px;line-height:2;font-weight:700;padding:5px 10px}ul,menu,dir{display:block;list-style-type:disc;-webkit-margin-before:1em;-webkit-margin-after:1em;-webkit-margin-start:0;-webkit-margin-end:0;-webkit-padding-start:40px}li{display:list-item}ol{display:block;list-style-type:decimal;-webkit-margin-before:1em;-webkit-margin-after:1em;-webkit-margin-start:0;-webkit-margin-end:0;-webkit-padding-start:40px}ul ul,ol ul{list-style-type:circle}ol ol ul,ol ul ul,ul ol ul,ul ul ul{list-style-type:square}code{font-family:Courier}pre{font-family:Courier}a{color:#82acc6;text-decoration:underline}center{text-align:center;display:block}strong,b{font-weight:bolder}i,em{font-style:italic}u{text-decoration:underline}big{font-size:bigger}small{font-size:smaller}sub{font-size:smaller;vertical-align:sub}sup{font-size:smaller;vertical-align:super}s,strike,del{text-decoration:line-through}tt,code,kbd,samp{font-family:monospace}pre,xmp,plaintext,listing{display:block;font-family:monospace;white-space:pre;margin-top:1em;margin-right:0;margin-bottom:1em;margin-left:0}div{display:block}link{display:none}meta{display:none}script{display:none}hr{display:block;-webkit-margin-before:.5em;-webkit-margin-after:.5em;-webkit-margin-start:auto;-webkit-margin-end:auto;border-style:inset;border-width:1px}h1{display:block;font-size:2em;-webkit-margin-before:.67em;-webkit-margin-after:.67em;-webkit-margin-start:0;-webkit-margin-end:0;font-weight:700;color:#4ba733}h2{display:block;font-size:1.5em;-webkit-margin-before:.83em;-webkit-margin-after:.83em;-webkit-margin-start:0;-webkit-margin-end:0;font-weight:700;color:#4ba733}h2.references{color:#000;font-size:12px}h3{display:block;font-size:1.17em;-webkit-margin-before:1em;-webkit-margin-after:1em;-webkit-margin-start:0;-webkit-margin-end:0;font-weight:700;color:#4ba733}h4{display:block;-webkit-margin-before:1.33em;-webkit-margin-after:1.33em;-webkit-margin-start:0;-webkit-margin-end:0;font-weight:700}h5{display:block;font-size:.83em;-webkit-margin-before:1.67em;-webkit-margin-after:1.67em;-webkit-margin-start:0;-webkit-margin-end:0;font-weight:700}h6{display:block;font-size:.67em;-webkit-margin-before:2.33em;-webkit-margin-after:2.33em;-webkit-margin-start:0;-webkit-margin-end:0;font-weight:700}.img-caption{font-size:14px;line-height:2}div p.editors-note{background-color:#eee;background-image:none;border-top:0 dashed #eee;border-bottom:0 dashed #eee;font-size:14px;line-height:2;font-weight:700;padding:5px 10px}blockquote{color:#999;font-size:12px;border-left:1px solid #d9d9d9;padding:5px 20px;margin:7px 0}.document-figure{color:#999;font-size:12px;text-align:center;margin:10px auto}html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline;-webkit-text-size-adjust:none}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}table{border-collapse:collapse;border-spacing:0}body{background-color:#F7F7F7;font-family:\"Microsoft YaHei\",\"WenQuanYi Micro Hei\",SimHei,Tahoma,sans-serif;line-height:1.57}.container{width:640px;margin:0 auto}.article{color:#464646;font-size:18px;line-height:1.5em;padding:0 40px;background-color:#fafafa;line-height:1.8;text-align:justify}.article-header .title{color:#353535;font-size:23px;line-height:1.3em;padding:20px 0 8px}.article-header .publish{color:#B2B2B2;font-size:14px;line-height:14px;padding-right:8px;margin-bottom:15px}.article-header .publish span{line-height:14px}.article-header .publish .author{margin-right:10px;position:relative}.article-header .publish .author:after{content:'';background:#C1C1C1;position:absolute;right:-6px;top:8px;width:2px;height:2px}.content-paragraph{background-color:#EEE;padding:15px;margin:40px 0}.content *{line-height:1.5em!important}.content h1,.content h2,.content h3,.content h4,.content h5{font-weight:700;margin-bottom:20px;color:#333}.content h1,.content h2{font-size:20px}.content h3{font-size:18px}.content h4{font-size:16px}.content h5{font-size:14px}.content p,.content div{margin-bottom:1.5em}.content em{font-style:italic}.content ul{list-style:disc;padding-left:20px;margin-bottom:1.5em}.content ol{list-style:decimal;padding-left:20px;margin-bottom:1.5em}.content blockquote{border-left:3px solid rgba(9,174,93,.3);padding:0 0 0 10px;margin-bottom:20px}.content strong{font-weight:700;color:#333}.content a{color:#09AE5D;text-decoration:none}.content img{max-width:100%;height:auto!important;display:inline-block;margin-bottom:1.5em;opacity:0}.content img.load{background:url(../images/2042b474.load.gif) #fff no-repeat center}.content .img-caption{position:relative;width:100%;text-align:center;color:#9c9c9c!important;font-size:14px!important}.content .img-caption img{margin-bottom:5px}.content .img-caption span{display:inline-block;width:100%;text-align:center;color:#9c9c9c!important;font-size:14px!important}.article-source{font-size:18px;color:#999}.article-source a{color:#999;text-decoration:none}.clearfix:before,.clearfix:after{content:\" \";display:table;clear:both}.rela-wrap{margin-top:20px;padding:5px 10px 0;border:1px solid rgba(206,206,206,.5);background-color:#f1f1f1;font-size:16px}.rela-wrap a{color:#607fa6;text-decoration:none}.rela-wrap .rela-title{margin-bottom:5px;color:#09ae5d}.rela-wrap .rela-list{list-style:none}.rela-wrap .rela-list li{padding:12px 0;border-top:1px solid rgba(206,206,206,.5)}.rela-wrap .rela-list li:active,.rela-wrap .rela-list li:visited{background-color:#E7E7E7}.rela-wrap .rela-list li a{position:relative;display:block;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;height:60px;color:#333;line-height:1;overflow:hidden;-webkit-tap-highlight-color:transparent;-webkit-user-select:none}.rela-wrap .article-title{display:-webkit-box;margin:auto 0;padding-right:90px;line-height:1.3em;max-height:2.6em;overflow:hidden;-webkit-line-clamp:2;-webkit-box-orient:vertical}.rela-wrap .img-wrap{position:absolute;right:0;top:0;width:80px}.rela-wrap .article-img{width:80px;height:60px}.night-mode.article{color:#b9b9b9;background-color:#2C3338}.night-mode .article-header .title{color:#ccc}.night-mode .article-header .publish{color:#7a7a7a}.night-mode .article-header .publish .author:after{background:#7a7a7a}.night-mode .content{color:#b9b9b9}.night-mode .content h1,.night-mode .content h2,.night-mode .content h3,.night-mode .content h4,.night-mode .content h5{color:#b9b9b9}.night-mode .content p{color:#b9b9b9}.night-mode .content a{color:#09AE5D}.night-mode .content .img-caption{color:#8D8D8D}.night-mode .content img.load{background:url(../images/2042b474.load.gif) #42484d no-repeat center}.night-mode .content strong{color:#b9b9b9}.night-mode .article-source{color:#7A7A7A}.night-mode .article-source a{color:#7A7A7A}.night-mode .rela-wrap{border:1px solid rgba(76,83,89,.5);background-color:#2F373C}.night-mode .rela-wrap a{color:#CBCBCB}.night-mode .rela-wrap .rela-title{color:#09ae5d}.night-mode .rela-wrap .rela-list li{border-top:1px solid rgba(110,110,110,.5)}.night-mode .rela-wrap .rela-list li:active,.night-mode .rela-wrap .rela-list li:visited{background-color:#373E43}.night-mode .rela-wrap .rela-list li a{color:#CBCBCB}@media (max-width:768px){body,.container{background-color:#FFF;margin:0;width:100%}.content-paragraph{margin:20px 0}.article{padding:20px 10px 10px;line-height:1.57}.content h1,.content h2,.content h3,.content h4,.content h5{margin-bottom:10px}.content p{margin-bottom:1.5em}.content img{margin-bottom:1.5em;width:100%;height:auto}.article-source{font-size:14px}.article-source a{font-size:14px}}"
  },
  {
    "path": "client/app/src/main/java/me/shouheng/references/MyApplication.java",
    "content": "package me.shouheng.references;\n\nimport com.alibaba.android.arouter.launcher.ARouter;\nimport com.meituan.android.walle.WalleChannelReader;\nimport com.umeng.commonsdk.UMConfigure;\nimport com.umeng.message.IUmengRegisterCallback;\nimport com.umeng.message.PushAgent;\n\nimport me.shouheng.commons.BaseApplication;\nimport me.shouheng.commons.config.Configs;\nimport me.shouheng.commons.tools.LogUtils;\n\n/**\n * @author shouh\n * @version $Id: ModuleGuokrApp, v 0.1 2018/6/6 22:30 shouh Exp$\n */\npublic class MyApplication extends BaseApplication {\n\n    private static MyApplication application;\n\n    public static MyApplication getContext() {\n        return application;\n    }\n\n    @Override\n    public void onCreate() {\n        super.onCreate();\n        application = this;\n\n        ARouter.init(this);\n\n        String channel = WalleChannelReader.getChannel(this);\n        UMConfigure.init(this, Configs.APP_KEY, channel, UMConfigure.DEVICE_TYPE_PHONE, Configs.UMENG_MESSAGE_SECRET);\n        UMConfigure.setLogEnabled(true);\n\n        PushAgent pushAgent = PushAgent.getInstance(this);\n        pushAgent.register(new IUmengRegisterCallback() {\n            @Override\n            public void onSuccess(String s) {\n                LogUtils.d(\"------\" + s);\n            }\n\n            @Override\n            public void onFailure(String s, String s1) {\n                LogUtils.d(\"------ s: \" + s + \" s1: \" + s1);\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "client/app/src/main/java/me/shouheng/references/view/intro/AppIntroActivity.java",
    "content": "package me.shouheng.references.view.intro;\n\nimport android.os.Bundle;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.github.paolorotolo.appintro.AppIntro;\n\nimport me.shouheng.commons.config.BaseConstants;\n\n@Route(path = BaseConstants.INTRO)\npublic class AppIntroActivity extends AppIntro {\n\n    @Override\n    public void init(Bundle savedInstanceState) {\n        addSlide(new IntroSlide1(), getApplicationContext());\n        addSlide(new IntroSlide2(), getApplicationContext());\n        addSlide(new IntroSlide3(), getApplicationContext());\n        addSlide(new IntroSlide4(), getApplicationContext());\n    }\n\n    @Override\n    public void onSkipPressed() {\n\n    }\n\n    @Override\n    public void onDonePressed() {\n        finish();\n    }\n\n    @Override\n    public void onBackPressed() {}\n}\n"
  },
  {
    "path": "client/app/src/main/java/me/shouheng/references/view/intro/IntroFragment.java",
    "content": "package me.shouheng.references.view.intro;\n\nimport android.os.Bundle;\n\nimport androidx.annotation.Nullable;\nimport androidx.fragment.app.Fragment;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.ImageView;\nimport android.widget.TextView;\n\nimport me.shouheng.references.R;\n\n\npublic class IntroFragment extends Fragment {\n\n\tprotected View background;\n\tprotected TextView title;\n\tprotected ImageView image;\n\tprotected ImageView imageSmall;\n\tprotected TextView description;\n\n\t@Override\n\tpublic View onCreateView(@Nullable LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\n\t\tif (inflater == null) {\n\t\t\tthrow new IllegalArgumentException(\"The inflater is null exception.\");\n\t\t}\n\t\tView root = inflater.inflate(R.layout.fragment_intro_slide, container, false);\n\t\tbackground = root.findViewById(R.id.intro_background);\n\t\ttitle = root.findViewById(R.id.intro_title);\n\t\timage = root.findViewById(R.id.intro_image);\n\t\timageSmall = root.findViewById(R.id.intro_image_small);\n\t\tdescription = root.findViewById(R.id.intro_description);\n\t\treturn root;\n\t}\n}"
  },
  {
    "path": "client/app/src/main/java/me/shouheng/references/view/intro/IntroSlide1.java",
    "content": "package me.shouheng.references.view.intro;\n\nimport android.os.Bundle;\n\nimport me.shouheng.references.R;\n\n\n/**\n * Created by Wang Shouheng on 2017/12/6. */\npublic class IntroSlide1 extends IntroFragment {\n\n    @Override\n    public void onActivityCreated(Bundle savedInstanceState) {\n        super.onActivityCreated(savedInstanceState);\n        background.setBackgroundResource(R.color.intro_color_5);\n        title.setText(\"intro_1_title\");\n        image.setImageResource(R.drawable.ic_slide1);\n        description.setText(\"intro_1_description\");\n    }\n}\n"
  },
  {
    "path": "client/app/src/main/java/me/shouheng/references/view/intro/IntroSlide2.java",
    "content": "package me.shouheng.references.view.intro;\n\nimport android.os.Bundle;\n\nimport me.shouheng.references.R;\n\n\npublic class IntroSlide2 extends IntroFragment {\n\n\t@Override\n\tpublic void onActivityCreated(Bundle savedInstanceState) {\n\t\tsuper.onActivityCreated(savedInstanceState);\n\t\tbackground.setBackgroundResource(R.color.intro_color_2);\n\t\ttitle.setText(\"intro_2_title\");\n\t\timage.setImageResource(R.drawable.ic_slide2);\n\t\tdescription.setText(\"intro_2_description\");\n\t}\n}"
  },
  {
    "path": "client/app/src/main/java/me/shouheng/references/view/intro/IntroSlide3.java",
    "content": "package me.shouheng.references.view.intro;\n\nimport android.os.Bundle;\n\nimport me.shouheng.references.R;\n\n\npublic class IntroSlide3 extends IntroFragment {\n\n\t@Override\n\tpublic void onActivityCreated(Bundle savedInstanceState) {\n\t\tsuper.onActivityCreated(savedInstanceState);\n\t\tbackground.setBackgroundResource(R.color.intro_color_3);\n\t\ttitle.setText(\"intro_3_title\");\n\t\timage.setImageResource(R.drawable.ic_slide3);\n\t\tdescription.setText(\"intro_3_description\");\n\t}\n}"
  },
  {
    "path": "client/app/src/main/java/me/shouheng/references/view/intro/IntroSlide4.java",
    "content": "package me.shouheng.references.view.intro;\n\nimport android.os.Bundle;\n\nimport me.shouheng.references.R;\n\n\npublic class IntroSlide4 extends IntroFragment {\n\n\t@Override\n\tpublic void onActivityCreated(Bundle savedInstanceState) {\n\t\tsuper.onActivityCreated(savedInstanceState);\n\t\tbackground.setBackgroundResource(R.color.intro_color_4);\n\t\ttitle.setText(\"intro_4_title\");\n\t\timage.setImageResource(R.drawable.ic_slide4);\n\t\tdescription.setText(\"intro_4_description\");\n\t}\n}"
  },
  {
    "path": "client/app/src/main/java/me/shouheng/references/view/main/MainActivity.java",
    "content": "package me.shouheng.references.view.main;\n\nimport android.app.PendingIntent;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.content.pm.ShortcutInfo;\nimport android.content.pm.ShortcutInfo.Builder;\nimport android.content.pm.ShortcutManager;\nimport android.graphics.Color;\nimport android.graphics.drawable.Icon;\nimport android.net.Uri;\nimport android.os.Build.VERSION;\nimport android.os.Build.VERSION_CODES;\nimport android.os.Bundle;\n\nimport com.alibaba.android.arouter.launcher.ARouter;\nimport com.bumptech.glide.Glide;\nimport com.bumptech.glide.load.engine.DiskCacheStrategy;\nimport com.bumptech.glide.request.RequestOptions;\nimport com.mikepenz.fontawesome_typeface_library.FontAwesome;\nimport com.mikepenz.google_material_typeface_library.GoogleMaterial;\nimport com.mikepenz.iconics.IconicsDrawable;\nimport com.mikepenz.materialdrawer.AccountHeader;\nimport com.mikepenz.materialdrawer.AccountHeaderBuilder;\nimport com.mikepenz.materialdrawer.DrawerBuilder;\nimport com.mikepenz.materialdrawer.model.PrimaryDrawerItem;\nimport com.mikepenz.materialdrawer.model.ProfileDrawerItem;\nimport com.mikepenz.materialdrawer.model.ProfileSettingDrawerItem;\nimport com.mikepenz.materialdrawer.model.interfaces.IProfile;\n\nimport java.util.Arrays;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.LogUtils;\nimport me.shouheng.commons.tools.PalmUtils;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.references.R;\nimport me.shouheng.references.databinding.ActivityMainBinding;\n\npublic class MainActivity extends CommonActivity<ActivityMainBinding> {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_main;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        ARouter.getInstance().build(BaseConstants.INTRO).navigation();\n\n        getBinding().barLayout.toolbar.setTitle(R.string.menu_item_desc_0);\n        getBinding().barLayout.toolbar.setTitleTextColor(Color.BLACK);\n\n        setupDrawer(savedInstanceState);\n\n        createShortcut(this);\n\n        createPinnedShortcut(this);\n\n        getBinding().btnOpenQq.setOnClickListener(v -> {\n            boolean succeed = joinQQGroup(\"J7Yn-X7oWh-kHljVnxc87WhoyaXns5BY\");\n            LogUtils.d(succeed);\n        });\n\n        Glide.with(getContext())\n                .load(\"https://3-im.guokr.com/0lSlGxgGIQkSQVA_Ja0U3Gxo0tPNIxuBCIXElrbkhpEXBAAAagMAAFBO.png\")\n                .apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.AUTOMATIC))\n                .apply(RequestOptions.skipMemoryCacheOf(false))\n                .into(getBinding().iv);\n    }\n\n    /****************\n     *\n     * 发起添加群流程。群号：天天记账用户交流群(881808089) 的 key 为： J7Yn-X7oWh-kHljVnxc87WhoyaXns5BY\n     * 调用 joinQQGroup(J7Yn-X7oWh-kHljVnxc87WhoyaXns5BY) 即可发起手Q客户端申请加群 天天记账用户交流群(881808089)\n     *\n     * @param key 由官网生成的key\n     * @return 返回true表示呼起手Q成功，返回fals表示呼起失败\n     ******************/\n    public boolean joinQQGroup(String key) {\n        Intent intent = new Intent();\n        intent.setData(Uri.parse(\"mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26k%3D\" + key));\n        // 此Flag可根据具体产品需要自定义，如设置，则在加群界面按返回，返回手Q主界面，不设置，按返回会返回到呼起产品界面    //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\n        try {\n            startActivity(intent);\n            return true;\n        } catch (Exception e) {\n            // 未安装手Q或安装的版本不支持\n            return false;\n        }\n    }\n\n    private void setupDrawer(Bundle savedInstanceState) {\n        IProfile profile = new ProfileDrawerItem()\n                .withName(R.string.developer_name)\n                .withEmail(R.string.developer_email)\n                .withIcon(R.drawable.ic_account)\n                .withIdentifier(100);\n        ProfileSettingDrawerItem item1 = new ProfileSettingDrawerItem()\n                .withName(R.string.add_account)\n                .withIcon(new IconicsDrawable(this, GoogleMaterial.Icon.gmd_add).actionBar().paddingDp(5).colorRes(R.color.material_drawer_primary_text))\n                .withIdentifier(100000);\n        ProfileSettingDrawerItem item2 = new ProfileSettingDrawerItem()\n                .withName(R.string.manage_account)\n                .withIcon(GoogleMaterial.Icon.gmd_settings)\n                .withIdentifier(100001);\n\n        AccountHeader header = new AccountHeaderBuilder()\n                .withActivity(this)\n                .withHeaderBackground(R.drawable.header_bg)\n                .addProfiles(profile, item1, item2)\n                .build();\n\n        PrimaryDrawerItem drawerItem0 = new PrimaryDrawerItem()\n                .withName(R.string.menu_item_title_0)\n                .withDescription(R.string.menu_item_desc_0)\n                .withIcon(FontAwesome.Icon.faw_home)\n                .withIdentifier(0) // the id of menu item, used when setting click event\n                .withSelectedTextColor(PalmUtils.getColorCompact(R.color.accent))\n                .withSelectedIconColor(PalmUtils.getColorCompact(R.color.accent))\n                .withSelectable(true); // it the item has selected state\n        PrimaryDrawerItem drawerItem1 = new PrimaryDrawerItem()\n                .withName(R.string.menu_item_title_1)\n                .withDescription(R.string.menu_item_desc_1)\n                .withIcon(GoogleMaterial.Icon.gmd_featured_video)\n                .withIdentifier(1)\n                .withSelectedTextColor(PalmUtils.getColorCompact(R.color.accent))\n                .withSelectedIconColor(PalmUtils.getColorCompact(R.color.accent))\n                .withSelectable(false);\n        PrimaryDrawerItem drawerItem2 = new PrimaryDrawerItem()\n                .withName(R.string.menu_item_title_2)\n                .withDescription(R.string.menu_item_desc_2)\n                .withIcon(FontAwesome.Icon.faw_gamepad)\n                .withIdentifier(2)\n                .withSelectedTextColor(PalmUtils.getColorCompact(R.color.accent))\n                .withSelectedIconColor(PalmUtils.getColorCompact(R.color.accent))\n                .withSelectable(false);\n        PrimaryDrawerItem drawerItem3 = new PrimaryDrawerItem()\n                .withName(R.string.menu_item_title_3)\n                .withDescription(R.string.menu_item_desc_3)\n                .withIcon(FontAwesome.Icon.faw_paper_plane)\n                .withIdentifier(3)\n                .withSelectedTextColor(PalmUtils.getColorCompact(R.color.accent))\n                .withSelectedIconColor(PalmUtils.getColorCompact(R.color.accent))\n                .withSelectable(false);\n        PrimaryDrawerItem drawerItem4 = new PrimaryDrawerItem()\n                .withName(R.string.menu_item_title_4)\n                .withDescription(R.string.menu_item_desc_4)\n                .withIcon(FontAwesome.Icon.faw_app_store_ios)\n                .withIdentifier(4)\n                .withSelectedTextColor(PalmUtils.getColorCompact(R.color.accent))\n                .withSelectedIconColor(PalmUtils.getColorCompact(R.color.accent))\n                .withSelectable(false);\n        PrimaryDrawerItem drawerItem5 = new PrimaryDrawerItem()\n                .withName(R.string.menu_item_title_5)\n                .withDescription(R.string.menu_item_desc_5)\n                .withIcon(FontAwesome.Icon.faw_accusoft)\n                .withIdentifier(5)\n                .withSelectedTextColor(PalmUtils.getColorCompact(R.color.accent))\n                .withSelectedIconColor(PalmUtils.getColorCompact(R.color.accent))\n                .withSelectable(false);\n        PrimaryDrawerItem drawerItem6 = new PrimaryDrawerItem()\n                .withName(R.string.menu_item_title_6)\n                .withDescription(R.string.menu_item_desc_6)\n                .withIcon(FontAwesome.Icon.faw_ban)\n                .withIdentifier(6)\n                .withSelectedTextColor(PalmUtils.getColorCompact(R.color.accent))\n                .withSelectedIconColor(PalmUtils.getColorCompact(R.color.accent))\n                .withSelectable(false);\n        PrimaryDrawerItem drawerItem7 = new PrimaryDrawerItem()\n                .withName(R.string.menu_item_title_7)\n                .withDescription(R.string.menu_item_desc_7)\n                .withIcon(FontAwesome.Icon.faw_address_book)\n                .withIdentifier(7)\n                .withSelectedTextColor(PalmUtils.getColorCompact(R.color.accent))\n                .withSelectedIconColor(PalmUtils.getColorCompact(R.color.accent))\n                .withSelectable(false);\n//        ExpandableBadgeDrawerItem drawerItem3 = new ExpandableBadgeDrawerItem()\n//                .withName(R.string.menu_item_title_3)\n//                .withDescription(R.string.menu_item_desc_3)\n//                .withIcon(FontAwesome.Icon.faw_paper_plane)\n//                .withSelectable(false)\n//                .withSubItems(\n//                        new SecondaryDrawerItem().withName(R.string.menu_item_sub_title_1)\n//                                .withSelectable(false)\n//                                .withDescription(R.string.menu_item_sub_desc_1)\n//                                .withLevel(2)\n//                                .withIcon(GoogleMaterial.Icon.gmd_navigation)\n//                                .withIdentifier(2000),\n//                        new SecondaryDrawerItem().withName(R.string.menu_item_sub_title_2)\n//                                .withSelectable(false)\n//                                .withDescription(R.string.menu_item_sub_desc_2)\n//                                .withLevel(2)\n//                                .withIcon(GoogleMaterial.Icon.gmd_format_bold)\n//                                .withIdentifier(2001),\n//                        new SecondaryDrawerItem().withName(R.string.menu_item_sub_title_3)\n//                                .withSelectable(false)\n//                                .withDescription(R.string.menu_item_sub_desc_3)\n//                                .withLevel(2)\n//                                .withIcon(GoogleMaterial.Icon.gmd_format_bold)\n//                                .withIdentifier(2002),\n//                        new SecondaryDrawerItem().withName(R.string.menu_item_sub_title_4)\n//                                .withSelectable(false)\n//                                .withDescription(R.string.menu_item_sub_desc_4)\n//                                .withLevel(2)\n//                                .withIcon(GoogleMaterial.Icon.gmd_format_bold)\n//                                .withIdentifier(2003),\n//                        new SecondaryDrawerItem().withName(R.string.menu_item_sub_title_5)\n//                                .withSelectable(false)\n//                                .withDescription(R.string.menu_item_sub_desc_5)\n//                                .withLevel(2)\n//                                .withIcon(GoogleMaterial.Icon.gmd_format_bold)\n//                                .withIdentifier(2004)\n//                );\n\n        new DrawerBuilder()\n                .withActivity(this)\n                .withHasStableIds(true)\n                .addDrawerItems(drawerItem0, drawerItem1, drawerItem2, drawerItem3, drawerItem4,\n                        drawerItem5, drawerItem6, drawerItem7)\n                .withOnDrawerItemClickListener((view, position, drawerItem) -> {\n                    if (drawerItem == null) return false;\n                    switch ((int) drawerItem.getIdentifier()) {\n                        case 0: break;\n                        case 1:\n                            ARouter.getInstance()\n                                    .build(BaseConstants.LIVE_HOME)\n                                    .navigation();\n                            break;\n                        case 2:\n                            ARouter.getInstance()\n                                    .build(BaseConstants.GUOKR_NEWS)\n                                    .navigation();\n                            break;\n                        case 3:\n                            ARouter.getInstance()\n                                    .build(BaseConstants.LAYOUT_MENU)\n                                    .navigation();\n                            break;\n                        case 4:\n                            ARouter.getInstance()\n                                    .build(BaseConstants.LIBRARY_MENU)\n                                    .navigation();\n                            break;\n                        case 5:\n                            ARouter.getInstance()\n                                    .build(BaseConstants.EYEPETIZER_MENU)\n                                    .navigation();\n                            break;\n                        case 6:\n                            ARouter.getInstance()\n                                    .build(BaseConstants.ANIMATIONS_MENU)\n                                    .navigation();\n                            break;\n                        case 7:\n                            ARouter.getInstance()\n                                    .build(BaseConstants.ADVANCED_MENU)\n                                    .navigation();\n                            break;\n                    }\n                    return false;\n                })\n                .withAccountHeader(header)\n                .withSavedInstance(savedInstanceState)\n                .withShowDrawerOnFirstLaunch(true)\n                .build();\n    }\n\n    private void createShortcut(Context context) {\n        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N_MR1) {\n            ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);\n            ShortcutInfo shortcut = new ShortcutInfo.Builder(context, \"id1\")\n                    .setShortLabel(\"Website\")\n                    .setLongLabel(\"Open the website\")\n                    .setIcon(Icon.createWithResource(context, R.drawable.ic_account_circle_black_24dp))\n                    .setIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(\"https://www.mysite.example.com/\")))\n                    .build();\n\n            shortcutManager.setDynamicShortcuts(Arrays.asList(shortcut));\n        }\n    }\n\n    private void createPinnedShortcut(Context context) {\n        if (VERSION.SDK_INT >= VERSION_CODES.N_MR1) {\n            ShortcutManager mShortcutManager = context.getSystemService(ShortcutManager.class);\n\n            if (VERSION.SDK_INT >= VERSION_CODES.O) {\n                if (mShortcutManager.isRequestPinShortcutSupported()) {\n                    // Assumes there's already a shortcut with the ID \"my-shortcut\".\n                    // The shortcut must be enabled.\n                    ShortcutInfo pinShortcutInfo = new Builder(context, \"my-shortcut\")\n                            .setShortLabel(\"Pined shortcut\")\n                            .setLongLabel(\"Pined shortcut Pined shortcut\")\n                            .setIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(\"https://www.mysite.example.com/\")))\n                            .setIcon(Icon.createWithResource(context, R.drawable.ic_account_circle_black_24dp))\n                            .build();\n\n                    // Create the PendingIntent object only if your app needs to be notified\n                    // that the user allowed the shortcut to be pinned. Note that, if the\n                    // pinning operation fails, your app isn't notified. We assume here that the\n                    // app has implemented a method called createShortcutResultIntent() that\n                    // returns a broadcast intent.\n                    Intent pinnedShortcutCallbackIntent = mShortcutManager.createShortcutResultIntent(pinShortcutInfo);\n\n                    // Configure the intent so that your app's broadcast receiver gets\n                    // the callback successfully.For details, see PendingIntent.getBroadcast().\n                    PendingIntent successCallback = PendingIntent.getBroadcast(context, /* request code */ 0,\n                            pinnedShortcutCallbackIntent, /* flags */ 0);\n\n                    mShortcutManager.requestPinShortcut(pinShortcutInfo, successCallback.getIntentSender());\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "client/app/src/main/java/me/shouheng/references/viewmodel/MainViewModel.java",
    "content": "package me.shouheng.references.viewmodel;\n\nimport android.app.Application;\nimport androidx.lifecycle.AndroidViewModel;\nimport androidx.annotation.NonNull;\n\nimport javax.inject.Inject;\n\n/**\n * Created by WngShhng on 2018/6/7. */\npublic class MainViewModel extends AndroidViewModel {\n\n    @Inject\n    public MainViewModel(@NonNull Application application) {\n        super(application);\n    }\n}\n"
  },
  {
    "path": "client/app/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    tools:context=\".view.main.MainActivity\">\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <include android:id=\"@+id/bar_layout\" layout=\"@layout/layout_toolbar\"/>\n\n        <ScrollView\n            android:layout_below=\"@id/bar_layout\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\">\n\n            <LinearLayout\n                android:orientation=\"vertical\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\">\n\n                <TextView\n                    android:text=\"@string/what_for\"\n                    android:textSize=\"18sp\"\n                    android:textColor=\"@android:color/black\"\n                    android:textStyle=\"bold\"\n                    android:padding=\"8dp\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <TextView\n                    android:id=\"@+id/tv_what_for\"\n                    android:padding=\"8dp\"\n                    android:text=\"@string/what_for_detail\"\n                    android:layout_margin=\"8dp\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn_open_qq\"\n                    android:text=\"Launch QQ group\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <ImageView\n                    android:id=\"@+id/iv\"\n                    android:layout_width=\"100dp\"\n                    android:layout_height=\"100dp\" />\n\n            </LinearLayout>\n\n        </ScrollView>\n\n        <View android:layout_below=\"@id/bar_layout\"\n            android:background=\"@drawable/bg_toolbar_shade\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"5dp\"/>\n\n    </RelativeLayout>\n\n</layout>"
  },
  {
    "path": "client/app/src/main/res/layout/fragment_intro_slide.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:id=\"@+id/intro_background\"\n    android:background=\"#2196f3\"\n    android:orientation=\"vertical\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <TextView\n        android:id=\"@+id/intro_title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\"\n        android:gravity=\"center\"\n        android:fontFamily=\"sans-serif-thin\"\n        android:textColor=\"#ffffff\"\n        android:textSize=\"28sp\"\n        android:paddingTop=\"@dimen/intro_top_padding\"\n        android:paddingBottom=\"@dimen/intro_bottom_padding\"/>\n\n    <ImageView android:id=\"@+id/intro_image\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"5\"\n        android:layout_gravity=\"center\"\n        android:paddingLeft=\"@dimen/intro_side_padding\"\n        android:paddingStart=\"@dimen/intro_side_padding\"\n        android:paddingRight=\"@dimen/intro_side_padding\"\n        android:paddingEnd=\"@dimen/intro_side_padding\"/>\n\n    <ImageView android:id=\"@+id/intro_image_small\"\n        android:layout_width=\"450dp\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"5\"\n        android:layout_gravity=\"center\"\n        android:paddingTop=\"@dimen/intro_side_padding\"\n        android:paddingBottom=\"@dimen/intro_side_padding\"\n        android:paddingLeft=\"@dimen/intro_side_padding\"\n        android:paddingStart=\"@dimen/intro_side_padding\"\n        android:paddingRight=\"@dimen/intro_side_padding\"\n        android:paddingEnd=\"@dimen/intro_side_padding\"\n        android:visibility=\"gone\"/>\n\n    <TextView android:id=\"@+id/intro_description\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\"\n        android:gravity=\"center\"\n        android:textColor=\"#ffffff\"\n        android:paddingLeft=\"64dp\"\n        android:paddingRight=\"64dp\"\n        android:textSize=\"16sp\"\n        android:paddingTop=\"@dimen/intro_top_padding\"\n        android:paddingBottom=\"@dimen/intro_bottom_padding\"/>\n\n    <TextView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"64dp\"/>\n\n</LinearLayout>"
  },
  {
    "path": "client/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "client/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "client/app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#FAFAFA</color>\n    <color name=\"colorPrimaryDark\">#FAFAFA</color>\n    <color name=\"colorAccent\">#0078FF</color>\n\n    <color name=\"dark_theme_background\">#2E2E2E</color>\n    <color name=\"dark_theme_foreground\">#3F3F3F</color>\n\n    <color name=\"light_theme_background\">#FAFAFA</color>\n\n    <color name=\"intro_color_1\">#222222</color>\n    <color name=\"intro_color_2\">#c52829</color>\n    <color name=\"intro_color_3\">#f77910</color>\n    <color name=\"intro_color_4\">#21dba4</color>\n    <color name=\"intro_color_5\">#9C27B0</color>\n\n    <color name=\"colorNavItemUnselected\">#757575</color>\n    <color name=\"colorNavItemSelected\">@color/colorAccent</color>\n</resources>\n"
  },
  {
    "path": "client/app/src/main/res/values/dimens.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <dimen name=\"intro_top_padding\">32dp</dimen>\n    <dimen name=\"intro_bottom_padding\">24dp</dimen>\n    <dimen name=\"intro_side_padding\">64dp</dimen>\n\n    <dimen name=\"bottom_nav_height\">56dp</dimen>\n\n</resources>"
  },
  {
    "path": "client/app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">安卓开发参考</string>\n\n    <string name=\"settings_short_name\">short name</string>\n    <string name=\"settings_long_name\">long name</string>\n    <string name=\"settings_disable_msg\">disable message</string>\n</resources>\n"
  },
  {
    "path": "client/app/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <style name=\"AppTheme\" parent=\"Theme.MaterialComponents.Light.NoActionBar.Bridge\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/light_theme_background</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n\n        <item name=\"colorPrimaryVariant\">@android:color/holo_red_light</item>\n        <item name=\"colorSecondaryVariant\">@android:color/holo_orange_light</item>\n        <item name=\"colorSurface\">@android:color/holo_blue_light</item>\n        <item name=\"colorOnPrimary\">@android:color/holo_blue_light</item>\n        <item name=\"colorOnSecondary\">@android:color/holo_purple</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "client/app/src/main/res/xml/provider_paths.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<paths xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <external-path name=\"external_files\" path=\".\"/>\n</paths>"
  },
  {
    "path": "client/app/src/main/res/xml/shortcuts.xml",
    "content": "<shortcuts xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <shortcut android:shortcutId=\"intro\"\n        android:enabled=\"true\"\n        android:icon=\"@drawable/ic_account_circle_black_24dp\"\n        android:shortcutShortLabel=\"@string/settings_short_name\"\n        android:shortcutLongLabel=\"@string/settings_long_name\"\n        android:shortcutDisabledMessage=\"@string/settings_disable_msg\">\n        <intent\n            android:action=\"android.intent.action.VIEW\"\n            android:targetPackage=\"me.shouheng.references\"\n            android:targetClass=\"me.shouheng.references.view.intro.AppIntroActivity\" />\n        <categories android:name=\"android.shortcut.conversation\" />\n    </shortcut>\n    <shortcut android:shortcutId=\"main\"\n        android:enabled=\"true\"\n        android:icon=\"@drawable/ic_account_circle_black_24dp\"\n        android:shortcutShortLabel=\"@string/settings_short_name\"\n        android:shortcutLongLabel=\"@string/settings_long_name\"\n        android:shortcutDisabledMessage=\"@string/settings_disable_msg\">\n        <!--the package name should be the same as the app package name-->\n        <intent\n            android:action=\"android.intent.action.VIEW\"\n            android:targetPackage=\"me.shouheng.references\"\n            android:targetClass=\"me.shouheng.references.view.main.MainActivity\" />\n        <categories android:name=\"android.shortcut.conversation\" />\n    </shortcut>\n</shortcuts>"
  },
  {
    "path": "client/app/src/test/java/me/shouheng/references/ExampleUnitTest.java",
    "content": "package me.shouheng.references;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "client/build.gradle",
    "content": "buildscript {\n    repositories {\n        google()\n        jcenter()\n        maven { url 'https://maven.fabric.io/public' }\n        maven { url 'https://dl.bintray.com/umsdk/release' }\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.2.1'\n        classpath 'io.fabric.tools:gradle:1.25.4'\n        classpath 'com.meituan.android.walle:plugin:1.1.6'\n        classpath 'com.tencent.mm:AndResGuard-gradle-plugin:1.2.13'\n        classpath \"net.rdrei.android.buildtimetracker:gradle-plugin:0.11.1\"\n        classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.8.4'\n    }\n}\n\nplugins {\n    id \"net.rdrei.android.buildtimetracker\" version \"0.11.0\"\n}\n\nbuildtimetracker {\n    reporters {\n        csv {\n            output \"build/times.csv\"\n            append true\n            header false\n        }\n        summary {\n            ordered false\n            threshold 50\n            barstyle \"unicode\"\n        }\n        csvSummary {\n            csv \"build/times.csv\"\n        }\n    }\n}\n\nallprojects {\n    repositories {\n        google()\n        jcenter()\n        mavenCentral()\n        maven { url \"https://jitpack.io\" }\n        maven { url \"https://maven.google.com/\"}\n        maven { url 'https://maven.fabric.io/public' }\n        maven { url 'https://dl.bintray.com/umsdk/release' }\n    }\n}\n\next {\n    compileSdkVersion = 28\n    buildToolsVersion = '28.0.2'\n    targetSdkVersion = compileSdkVersion\n    minSdkVersion = 17\n\n    androidX = '1.0.0'\n    constraintLayout = '2.0.0-alpha2'\n\n    rxJava = '2.2.0'\n    rxAndroid = '2.0.2'\n\n    dagger = '2.15'\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "client/gradle/wrapper/gradle-wrapper.properties",
    "content": "#Tue Oct 30 20:12:17 CST 2018\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-4.6-all.zip\n"
  },
  {
    "path": "client/gradle.properties",
    "content": "org.gradle.daemon=true\norg.gradle.configureondemond=true\norg.gradle.jvmargs=-Xmx1024m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8\norg.gradle.parallel=true\norg.gradle.caching=true\n\nisModuleApp=false\nisGuokrModuleApp=isModuleApp\nisLiveModuleApp=isModuleApp\nisLayoutModuleApp=isModuleApp\nisLibraryModuleApp=isModuleApp\nisEyepetizerModuleApp=isModuleApp\nisAnimationsModuleApp=isModuleApp\nisAdvancedModuleApp=isModuleApp\n\nandroid.useAndroidX=true\nandroid.enableJetifier=true"
  },
  {
    "path": "client/gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "client/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto init\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto init\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:init\n@rem Get command-line arguments, handling Windows variants\n\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\n\n:win9xME_args\n@rem Slurp the command line arguments.\nset CMD_LINE_ARGS=\nset _SKIP=2\n\n:win9xME_args_slurp\nif \"x%~1\" == \"x\" goto execute\n\nset CMD_LINE_ARGS=%*\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "client/settings.gradle",
    "content": "include ':app', ':commons', ':guokr', ':live', ':layout', ':libraries', ':eyepetizer', ':knife-annotation',  ':knife-api', ':knife-compiler', ':animations', ':advanced'\nproject(':commons').projectDir = new File('../commons')\nproject(':guokr').projectDir = new File('../guokr')\nproject(':live').projectDir = new File('../live')\nproject(':layout').projectDir = new File('../layout')\nproject(':libraries').projectDir = new File('../libraries')\nproject(':eyepetizer').projectDir = new File('../eyepetizer')\nproject(':knife-annotation').projectDir = new File('../knife-annotation')\nproject(':knife-api').projectDir = new File('../knife-api')\nproject(':knife-compiler').projectDir = new File('../knife-compiler')\nproject(':animations').projectDir = new File('../animations')\nproject(':advanced').projectDir = new File('../advanced')"
  },
  {
    "path": "commons/.gitignore",
    "content": "# Built application files\n*.apk\n*.ap_\n\n# Files for the ART/Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbin/\ngen/\nout/\n\n# Gradle files\n.gradle/\nbuild/\n.idea\n\n# Local configuration file (sdk path, etc)\nlocal.properties\n\n# Proguard folder generated by Eclipse\nproguard/\n\n# Log Files\n*.log\n\n# Android Studio Navigation editor temp files\n.navigation/\n\n# Android Studio captures folder\ncaptures/\n\n# IntelliJ\n*.iml\n.idea/workspace.xml\n.idea/tasks.xml\n.idea/gradle.xml\n.idea/dictionaries\n.idea/libraries\n\n# Keystore files\n# Uncomment the following line if you do not want to check your keystore files in.\n#*.jks\n\n# External native build folder generated in Android Studio 2.2 and later\n.externalNativeBuild\n\n# Google Services (e.g. APIs or Firebase)\ngoogle-services.json\n\n# Freeline\nfreeline.py\nfreeline/\nfreeline_project_description.json\n"
  },
  {
    "path": "commons/build.gradle",
    "content": "apply plugin: 'com.android.library'\n\nandroid {\n    compileSdkVersion rootProject.ext.compileSdkVersion\n    defaultConfig {\n        minSdkVersion rootProject.ext.minSdkVersion\n        targetSdkVersion rootProject.ext.targetSdkVersion\n        versionCode 1\n        versionName \"1.0\"\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n        javaCompileOptions {\n            annotationProcessorOptions {\n                arguments = [ moduleName : project.getName() ]\n            }\n        }\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n    // use data binding\n    dataBinding {\n        enabled = true\n    }\n    // use java 8 language\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n    // use external libs folder\n    sourceSets {\n        main {\n            jniLibs.srcDirs = ['libs']\n        }\n    }\n}\n\ndependencies {\n    api fileTree(include: ['*.jar'], dir: 'libs')\n    testImplementation 'junit:junit:4.12'\n    androidTestImplementation 'androidx.test:runner:1.1.0'\n    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'\n    // support\n    api \"androidx.recyclerview:recyclerview:${androidX}\"\n    api \"androidx.palette:palette:${androidX}\"\n    api \"androidx.cardview:cardview:${androidX}\"\n    api \"androidx.appcompat:appcompat:1.0.2\"\n    api \"androidx.recyclerview:recyclerview:${androidX}\"\n    api \"androidx.annotation:annotation:${androidX}\"\n    api \"androidx.legacy:legacy-support-v4:${androidX}\"\n    api \"androidx.constraintlayout:constraintlayout:${constraintLayout}\"\n    api 'com.google.android.material:material:1.1.0-alpha01'\n    // architecture\n    api 'androidx.lifecycle:lifecycle-runtime:2.0.0'\n    api 'androidx.lifecycle:lifecycle-extensions:2.0.0'\n    annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.0.0'\n    // leakcanary\n    debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.2'\n    releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.1'\n    // multidex\n    api 'androidx.multidex:multidex:2.0.0'\n    // time\n    api 'org.ocpsoft.prettytime:prettytime:4.0.1.Final'\n    api 'joda-time:joda-time:2.9.9'\n    // io\n    api 'commons-io:commons-io:2.6'\n    // image compress\n    api 'top.zibin:Luban:1.1.3'\n    // recycler\n    api 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.43-alpha1'\n    api 'com.yanzhenjie:recyclerview-swipe:1.1.4'\n    api 'com.timehop.stickyheadersrecyclerview:library:0.4.3@aar'\n    // glide\n    api 'com.github.bumptech.glide:glide:4.8.0'\n    annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'\n    api ('com.github.bumptech.glide:okhttp3-integration:4.8.0') {\n        transitive = false\n    }\n    // debug tools\n    implementation 'com.facebook.stetho:stetho:1.5.0'\n    // fabric\n    api('com.crashlytics.sdk.android:crashlytics:2.9.2@aar') {\n        transitive = true\n    }\n    // dagger\n    api \"com.google.dagger:dagger:$dagger\"\n    api \"com.google.dagger:dagger-android:$dagger\"\n    api \"com.google.dagger:dagger-android-support:$dagger\"\n    annotationProcessor \"com.google.dagger:dagger-compiler:$dagger\"\n    annotationProcessor \"com.google.dagger:dagger-android-processor:$dagger\"\n    // retrofit\n    api 'com.squareup.retrofit2:retrofit:2.4.0'\n    api 'com.squareup.retrofit2:converter-gson:2.4.0'\n    api 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'\n    // rx-java\n    api \"io.reactivex.rxjava2:rxjava:$rxJava\"\n    api \"io.reactivex.rxjava2:rxandroid:$rxAndroid\"\n    // router\n    api 'com.alibaba:arouter-api:1.3.1'\n    annotationProcessor 'com.alibaba:arouter-compiler:1.1.4'\n    // walle\n    api 'com.meituan.android.walle:library:1.1.6'\n    // umeng\n    api  'com.umeng.umsdk:common:1.5.4'\n    api  'com.umeng.umsdk:analytics:7.5.4'\n    // PushSDK必须依赖utdid库，所以需要加入对应依赖\n    api 'com.umeng.umsdk:utdid:1.1.5.3'\n    // PushSDK\n    api 'com.umeng.umsdk:push:5.0.2'\n    // player\n    api files('libs/pldroid-player-1.5.0.jar')\n    // timer\n    api 'com.jakewharton.timber:timber:4.7.1'\n}\n"
  },
  {
    "path": "commons/proguard-rules.pro",
    "content": ""
  },
  {
    "path": "commons/src/androidTest/java/me/shouheng/commons/ExampleInstrumentedTest.java",
    "content": "package me.shouheng.commons;\n\nimport android.content.Context;\nimport androidx.test.InstrumentationRegistry;\nimport androidx.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"me.shouheng.commons.test\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "commons/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"me.shouheng.commons\" >\n    <uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />\n</manifest>\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/BaseApplication.java",
    "content": "package me.shouheng.commons;\n\nimport android.app.Application;\nimport androidx.multidex.MultiDex;\n\nimport com.alibaba.android.arouter.launcher.ARouter;\nimport com.crashlytics.android.Crashlytics;\nimport com.facebook.stetho.Stetho;\nimport com.squareup.leakcanary.LeakCanary;\n\nimport io.fabric.sdk.android.Fabric;\nimport timber.log.Timber;\nimport timber.log.Timber.DebugTree;\n\n/**\n * @author shouh\n * @version $Id: BaseApplication, v 0.1 2018/6/6 21:58 shouh Exp$\n */\npublic abstract class BaseApplication extends Application {\n\n    private static BaseApplication instance;\n\n    public static BaseApplication getContext() {\n        return instance;\n    }\n\n    @Override\n    public void onCreate() {\n        super.onCreate();\n\n        instance = this;\n\n        MultiDex.install(this);\n\n        LeakCanary.install(this);\n\n        Fabric.with(this, new Crashlytics());\n\n        if (BuildConfig.DEBUG) {\n            Stetho.initializeWithDefaults(this);\n            ARouter.openLog();\n            ARouter.openDebug();\n        }\n\n        if (BuildConfig.DEBUG) {\n            Timber.plant(new DebugTree());\n        }\n    }\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/config/BaseConstants.java",
    "content": "package me.shouheng.commons.config;\n\n/**\n * Created by WngShhng on 2018/6/7.*/\npublic interface BaseConstants {\n\n    // region request codes\n    int REQUEST_PERMISSION_STORAGE = 0x0006;\n    int REQUEST_PERMISSION_PHONE_STATE = 0x0007;\n    int REQUEST_PERMISSION_LOCATION = 0x0008;\n    int REQUEST_PERMISSION_MICROPHONE = 0x0009;\n    int REQUEST_PERMISSION_SMS = 0x000A;\n    int REQUEST_PERMISSION_SENSORS = 0x000B;\n    int REQUEST_PERMISSION_CONTACTS = 0x000C;\n    int REQUEST_PERMISSION_CAMERA = 0x000D;\n    int REQUEST_PERMISSION_CALENDAR = 0x000E;\n    // endregion\n\n    String INTRO = \"/app/intro\";\n\n    String LIVE_HOME = \"/live/home\";\n    String LIVE_DETAIL = \"/live/detail\";\n    String LIVE_DETAIL_EXTRA_ROOM_TYPE = \"__extra_room_type\";\n    String LIVE_DETAIL_EXTRA_UID = \"__extra_uid\";\n    String LIVE_DETAIL_EXTRA_THUMB = \"__extra_thumb\";\n    String LIVE_DETAIL_FULL_SCREEN = \"/live/detail/fullscreen\";\n    String LIVE_DETAIL_FULL_SCREEN_EXTRA_KEY_UID = \"__extra_uid\";\n    String LIVE_DETAIL_FULL_SCREEN_EXTRA_KEY_THUMB = \"__extra_thumb\";\n    String LIVE_DETAIL_ROOM = \"/live/detail/room\";\n    String LIVE_DETAIL_ROOM_EXTRA_KEY_UID = \"__extra_uid\";\n    String LIVE_DETAIL_ROOM_EXTRA_KEY_THUMB = \"__extra_thumb\";\n\n    String GUOKR_NEWS = \"/guokr/news\";\n    String GUOKR_NEWS_LIST = \"/guokr/news/list\";\n    String GUOKR_NEWS_DETAIL = \"/guokr/news/detail\";\n    String GUOKR_NEWS_DETAIL_EXTRA_KEY_ARTICLE_ID = \"__extra_article_id\";\n    String GUOKR_NEWS_DETAIL_EXTRA_KEY_ARTICLE_TITLE = \"__extra_article_title\";\n\n    String LAYOUT_NORMAL_FRAGMENT = \"/layout/normal_fragment\";\n    String LAYOUT_NORMAL_FRAGMENT_EXTRA_TITLE = \"__extra_title\";\n    String LAYOUT_NORMAL_FRAGMENT_EXTRA_CONTENT = \"__extra_content\";\n    String LAYOUT_NORMAL_FRAGMENT_EXTRA_SHOW_TOOLBAR = \"__extra_show_toolbar\";\n    String LAYOUT_NAVIGATION = \"/layout/navigation\";\n    String LAYOUT_BOTTOM_SHEET = \"/layout/bottom_sheet\";\n    String LAYOUT_COLLAPSE_BAR = \"/layout/collapse_bar\";\n    String LAYOUT_SCROLLING = \"/layout/scrolling\";\n    String LAYOUT_TABBED = \"/layout/tabbed\";\n    String LAYOUT_MENU = \"/layout/menu\";\n    String LAYOUT_PAGER_FRAGMENT = \"/layout/pager\";\n    String LAYOUT_DRAWER = \"/layout/drawer\";\n    String LAYOUT_VIEW_SYSTEM = \"/layout/view_system\";\n    String LAYOUT_VIEW_ANIMATE = \"/layout/view_animate\";\n    String LAYOUT_SUPPORT_28 = \"/layout/support_28\";\n    String LAYOUT_BOTTOM_APP_BAR = \"/layout/bottom_app_bar\";\n    String LAYOUT_ADAPTER = \"/layout/adapter\";\n    String LAYOUT_ADAPTER_ARG_USE_ADAPTER = \"layout_adapter_arg_use_adapter\";\n    String LAYOUT_SWIPE_BACK = \"/layout/swipe_back\";\n    String LAYOUT_EDIT_LAYOUT = \"/layout/edit_layout\";\n\n    String LIBRARY_MENU = \"/library/menu\";\n    String LIBRARY_EVENT_BUS_ACTIVITY1 = \"/library/event_bus/activity1\";\n    String LIBRARY_EVENT_BUS_ACTIVITY2 = \"/library/event_bus/activity2\";\n    String LIBRARY_RX_JAVA = \"/library/rxjava\";\n    String LIBRARY_RX_JAVA_BUS = \"/library/rxjava_bus\";\n    String LIBRARY_CLIP_PIC = \"/library/clip_picture\";\n    String LIBRARY_TIMBER = \"/library/timber\";\n    String LIBRARY_MY_KNIFE = \"/library/my_knife\";\n    String LIBRARY_FINGERPRIINT_IDENTIFY = \"/library/fingerprint_identify\";\n    String LIBRARY_WORK_MANAGER = \"/library/work_manager\";\n    String LIBRARY_FRAGMENT_DEMO = \"/library/fragment_demo\";\n    String LIBRARY_FRAGMENT_DEMO_HAS_CHILD = \"arg_fragment_demo_has_child\";\n    String LIBRARY_SERIAL = \"/library/serial\";\n    String LIBRARY_SERIAL_ARG_MONSTER = \"library_serial_arg_monster\";\n    String LIBRARY_HANDLER = \"/library/handler\";\n    String LIBRARY_COMPRESS = \"/library/compress\";\n\n    String EYEPETIZER_MENU = \"/eyepetizer/menu\";\n    String EYEPETIZER_CONTAINER = \"/eyepetizer/container\";\n    String EYEPETIZER_CONTAINER_ACTION_VIDEO_EXTRA_URL = \"__container_action_video_extra_url\";\n    String EYEPETIZER_VIDEO = \"/eyepetizer/video\";\n    String EYEPETIZER_VIDEO_EXTRA_URL = \"__extra_url\";\n    String EYEPETIZER_VIDEO_EXTRA_FULLSCREEN = \"__extra_fullscreen\";\n\n    String ANIMATIONS_MENU = \"/animations/menu\";\n    String ANIMATIONS_CIRCLE_REVEAL = \"/animations/circle_reveal\";\n    String ANIMATIONS_DRAWABLE = \"/animations/drawable\";\n\n    String ADVANCED_MENU = \"/advanced/menu\";\n    String ADVANCED_REMOTE = \"/advanced/remote\";\n    String ADVANCED_REMOTE_ARG_CONTENT = \"advanced_remote_arg_content\";\n    String ADVANCED_REMOTE2 = \"/advanced/remote2\";\n    String ADVANCED_REMOTE2_ARG_CONTENT = \"advanced_remote_arg_content\";\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/config/Configs.java",
    "content": "package me.shouheng.commons.config;\n\n/**\n * Created by WngShhng on 2018/8/2.*/\npublic interface Configs {\n    String APP_KEY = \"5b62ef2df43e4841b70003cb\";\n    String UMENG_MESSAGE_SECRET = \"9d944b47eaf95b1d4c200bed2a93c3eb\";\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/di/AppComponent.java",
    "content": "package me.shouheng.commons.di;\n\nimport android.app.Application;\n\nimport javax.inject.Singleton;\n\nimport dagger.BindsInstance;\nimport dagger.Component;\nimport dagger.android.AndroidInjector;\nimport me.shouheng.commons.BaseApplication;\nimport me.shouheng.commons.di.module.AppModule;\n\n/**\n * Will auto-generate {@link DaggerAppComponent} see more details in it.\n *\n * @author shouh\n * @version $Id: AppComponent, v 0.1 2018/6/6 22:34 shouh Exp$\n */\n@Singleton\n@Component(modules = {AppModule.class})\npublic interface AppComponent extends AndroidInjector<BaseApplication> {\n\n    @Component.Builder\n    interface Builder {\n\n        @BindsInstance Builder application(Application application);\n\n        AppComponent build();\n    }\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/di/enums/ActivityScoped.java",
    "content": "package me.shouheng.commons.di.enums;\n\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\n\nimport javax.inject.Scope;\n\n/**\n * @author shouh\n * @version $Id: ActivityScoped, v 0.1 2018/6/6 22:48 shouh Exp$\n */\n@Documented\n@Scope\n@Retention(RetentionPolicy.RUNTIME)\npublic @interface ActivityScoped {\n\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/di/enums/ViewModelKey.java",
    "content": "package me.shouheng.commons.di.enums;\n\nimport androidx.lifecycle.ViewModel;\n\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\nimport dagger.MapKey;\n\n/**\n * Created by WngShhng on 2018/6/7.*/\n@Documented\n@Target({ElementType.METHOD})\n@Retention(RetentionPolicy.RUNTIME)\n@MapKey\npublic @interface ViewModelKey {\n    Class<? extends ViewModel> value();\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/di/module/AppModule.java",
    "content": "package me.shouheng.commons.di.module;\n\nimport java.util.concurrent.TimeUnit;\n\nimport javax.inject.Singleton;\n\nimport dagger.Module;\nimport dagger.Provides;\nimport okhttp3.OkHttpClient;\n\n/**\n * @author shouh\n * @version $Id: AppModule, v 0.1 2018/6/8 22:04 shouh Exp$\n */\n@Module\npublic class AppModule {\n\n    @Provides\n    @Singleton\n    OkHttpClient provideOkHttpClient() {\n        return new OkHttpClient.Builder()\n                .connectTimeout(10, TimeUnit.SECONDS)\n                .readTimeout(10, TimeUnit.SECONDS)\n                .writeTimeout(10, TimeUnit.SECONDS)\n                .build();\n    }\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/model/Resource.java",
    "content": "package me.shouheng.commons.model;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport static me.shouheng.commons.model.Status.*;\n\n\n/**\n * Created by wang shouheng on 2018/3/13. */\npublic class Resource<T> {\n\n    @NonNull\n    public Status status;\n\n    @Nullable\n    public T data;\n\n    @Nullable\n    public String message;\n\n    /**\n     * Reserved field */\n    private Long udf1;\n\n    private Resource(@NonNull Status status, @Nullable T data, @Nullable String message) {\n        this.status = status;\n        this.data = data;\n        this.message = message;\n    }\n\n    public static <T> Resource<T> success(@NonNull T data) {\n        return new Resource<>(SUCCESS, data, null);\n    }\n\n    public static <T> Resource<T> error(String msg, @Nullable T data) {\n        return new Resource<>(FAILED, data, msg);\n    }\n\n    public static <T> Resource<T> loading(@Nullable T data) {\n        return new Resource<>(LOADING, data, null);\n    }\n\n    public Long getUdf1() {\n        return udf1;\n    }\n\n    public void setUdf1(Long udf1) {\n        this.udf1 = udf1;\n    }\n\n    @Override\n    public String toString() {\n        return \"Resource{\" +\n                \"status=\" + status +\n                \", data=\" + data +\n                \", message='\" + message + '\\'' +\n                \", udf1=\" + udf1 +\n                '}';\n    }\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/model/Status.java",
    "content": "package me.shouheng.commons.model;\n\n/**\n * Created by wang shouheng on 2018/3/13. */\npublic enum  Status {\n    SUCCESS,\n    FAILED,\n    LOADING\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/rxbus/RxBus.java",
    "content": "package me.shouheng.commons.rxbus;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport io.reactivex.BackpressureStrategy;\nimport io.reactivex.Flowable;\nimport io.reactivex.android.schedulers.AndroidSchedulers;\nimport io.reactivex.disposables.CompositeDisposable;\nimport io.reactivex.disposables.Disposable;\nimport io.reactivex.functions.Consumer;\nimport io.reactivex.schedulers.Schedulers;\nimport io.reactivex.subjects.PublishSubject;\nimport io.reactivex.subjects.Subject;\n\n/**\n * Created by WngShhng on 2018/8/17.\n */\npublic class RxBus {\n\n    private static volatile RxBus rxBus;\n\n    private final Subject<Object> subject = PublishSubject.create().toSerialized();\n\n    private final Map<String, CompositeDisposable> disposableMap = new HashMap<>();\n\n    public static RxBus getRxBus() {\n        if (rxBus == null) {\n            synchronized (RxBus.class) {\n                if(rxBus == null) {\n                    rxBus = new RxBus();\n                }\n            }\n        }\n        return rxBus;\n    }\n\n    public void post(Object o){\n        subject.onNext(o);\n    }\n\n    public <T>Flowable<T> getObservable(Class<T> type){\n        return subject.toFlowable(BackpressureStrategy.BUFFER).ofType(type);\n    }\n\n    public <T> Disposable doSubscribe(Class<T> type, Consumer<T> next, Consumer<Throwable> error){\n        return getObservable(type)\n                .subscribeOn(Schedulers.io())\n                .observeOn(AndroidSchedulers.mainThread())\n                .subscribe(next,error);\n    }\n\n    public boolean hasObservers() {\n        return subject.hasObservers();\n    }\n\n    public void addSubscription(Object o, Disposable disposable) {\n        String key = String.valueOf(o.hashCode());\n        if (disposableMap.get(key) != null) {\n            disposableMap.get(key).add(disposable);\n        } else {\n            CompositeDisposable disposables = new CompositeDisposable();\n            disposables.add(disposable);\n            disposableMap.put(key, disposables);\n        }\n    }\n\n    public void unSubscribe(Object o) {\n        String key = String.valueOf(o.hashCode());\n        if (!disposableMap.containsKey(key)){\n            return;\n        }\n        if (disposableMap.get(key) != null) {\n            disposableMap.get(key).dispose();\n        }\n\n        disposableMap.remove(key);\n    }\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/tools/ColorUtils.java",
    "content": "package me.shouheng.commons.tools;\n\nimport android.content.res.ColorStateList;\nimport android.graphics.Color;\nimport android.graphics.drawable.Drawable;\nimport androidx.annotation.ColorInt;\nimport androidx.annotation.FloatRange;\nimport androidx.annotation.NonNull;\nimport androidx.core.graphics.drawable.DrawableCompat;\n\n/**\n * @author shouh\n * @version $Id: ColorUtils, v 0.1 2018/6/6 22:14 shouh Exp$\n */\npublic class ColorUtils {\n\n    private static final int DEFAULT_COLOR_ALPHA = 50;\n\n    public static Drawable tintDrawable(@NonNull Drawable drawable, @ColorInt int color) {\n        final Drawable wrappedDrawable = DrawableCompat.wrap(drawable.mutate());\n        DrawableCompat.setTintList(wrappedDrawable, ColorStateList.valueOf(color));\n        return wrappedDrawable;\n    }\n\n    public static int calStatusBarColor(int color) {\n        return calStatusBarColor(color, DEFAULT_COLOR_ALPHA);\n    }\n\n    public static int calStatusBarColor(int color, int alpha) {\n        float a = 1 - alpha / 255f;\n        int red = color >> 16 & 0xff;\n        int green = color >> 8 & 0xff;\n        int blue = color & 0xff;\n        red = (int) (red * a + 0.5);\n        green = (int) (green * a + 0.5);\n        blue = (int) (blue * a + 0.5);\n        return 0xff << 24 | red << 16 | green << 8 | blue;\n    }\n\n    public static int parseColor(String colorHex, @ColorInt int defaultValue) {\n        try {\n            return Color.parseColor(colorHex);\n        } catch (Exception e) {\n            return defaultValue;\n        }\n    }\n\n    public static @ColorInt int fadeColor(@ColorInt int color, @FloatRange(from = 0, to = 1) float rate) {\n        return (color & 0x00ffffff) | ((0xff - (int)(0xff * rate)) << 24);\n    }\n\n    public static int getBlackWhiteColor(int color) {\n        double darkness = 1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255;\n        if (darkness >= 0.5) {\n            return Color.WHITE;\n        } else return Color.BLACK;\n    }\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/tools/FragmentHelper.java",
    "content": "package me.shouheng.commons.tools;\n\nimport androidx.annotation.IdRes;\nimport androidx.fragment.app.Fragment;\nimport androidx.fragment.app.FragmentManager;\nimport androidx.fragment.app.FragmentTransaction;\nimport androidx.appcompat.app.AppCompatActivity;\n\n/**\n * Created by WngShhng on 2018/6/7.*/\npublic class FragmentHelper {\n\n    public static void replace(AppCompatActivity activity, Fragment fragment, @IdRes int containerId) {\n        replace(activity, fragment, containerId, false);\n    }\n\n    public static void replaceWithCallback(AppCompatActivity activity, Fragment fragment, @IdRes int containerId) {\n        replace(activity, fragment, containerId, true);\n    }\n\n    public static void replace(AppCompatActivity activity, android.app.Fragment fragment, @IdRes int containerId) {\n        replace(activity, fragment, containerId, false);\n    }\n\n    public static void replaceWithCallback(AppCompatActivity activity, android.app.Fragment fragment, @IdRes int containerId) {\n        replace(activity, fragment, containerId, true);\n    }\n\n    private static void replace(AppCompatActivity activity, android.app.Fragment fragment, @IdRes int containerId, boolean backStack) {\n        if (activity.isFinishing()) return;\n        android.app.FragmentManager fragmentManager = activity.getFragmentManager();\n        android.app.FragmentTransaction transaction = fragmentManager.beginTransaction();\n        if (backStack) transaction.addToBackStack(null);\n        transaction.replace(containerId, fragment).commit();\n    }\n\n    private static void replace(AppCompatActivity activity, Fragment fragment, @IdRes int containerId, boolean backStack) {\n        if (activity.isFinishing()) return;\n        FragmentManager fragmentManager = activity.getSupportFragmentManager();\n        FragmentTransaction transaction = fragmentManager.beginTransaction();\n        if (backStack) transaction.addToBackStack(null);\n        transaction.replace(containerId, fragment).commit();\n    }\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/tools/LogUtils.java",
    "content": "package me.shouheng.commons.tools;\n\nimport android.util.Log;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport me.shouheng.commons.BuildConfig;\n\npublic class LogUtils {\n\n    private static final boolean showLog = BuildConfig.DEBUG;\n\n    private final static String DEFAULT_LOG_TAG = \"logger\";\n\n    private static final int V = 1;\n    private static final int D = 2;\n    private static final int I = 3;\n    private static final int W = 4;\n    private static final int E = 5;\n\n    public static void v(Object obj) {\n        logs(LogUtils.V, null, obj);\n    }\n\n    public static void v(String tag, Object obj) {\n        logs(LogUtils.V, tag, obj);\n    }\n\n    public static void d(Object obj) {\n        logs(LogUtils.D, null, obj);\n    }\n\n    public static void d(String tag, Object obj) {\n        logs(LogUtils.D, tag, obj);\n    }\n\n    public static void i(Object obj) {\n        logs(LogUtils.I, null, obj);\n    }\n\n    public static void i(String tag, Object obj) {\n        logs(LogUtils.I, tag, obj);\n    }\n\n    public static void w(Object obj) {\n        logs(LogUtils.W, null, obj);\n    }\n\n    public static void w(String tag, Object obj) {\n        logs(LogUtils.W, tag, obj);\n    }\n\n    public static void e(Object obj) {\n        logs(LogUtils.E, null, obj);\n    }\n\n    public static void e(String tag, Object obj) {\n        logs(LogUtils.E, tag, obj);\n    }\n\n    private static void logs(int logType, String tagStr, Object obj) {\n        if (!showLog) {\n            return;\n        }\n        String msg;\n        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();\n\n        int index = 4;\n        String className = stackTrace[index].getFileName();\n        String methodName = stackTrace[index].getMethodName();\n        int lineNumber = stackTrace[index].getLineNumber();\n\n        String tag = (tagStr == null ? DEFAULT_LOG_TAG : tagStr);\n        methodName = methodName.substring(0, 1).toUpperCase() + methodName.substring(1);\n\n        StringBuilder stringBuilder = new StringBuilder();\n        stringBuilder.append(\"[ (\").append(className).append(\":\").append(lineNumber).append(\")#\").append(methodName).append(\" ] \");\n\n        if (obj == null) {\n            msg = \"Log with null Object\";\n        } else {\n            if (obj instanceof Map) {\n                msg = StringUtils.MapToString((Map<?, ?>) obj);\n            } else if (obj instanceof List) {\n                msg = StringUtils.ListToString((List<?>) obj);\n            } else {\n                msg = obj.toString();\n            }\n        }\n\n        if (msg != null) {\n            stringBuilder.append(msg);\n        }\n\n        String logStr = stringBuilder.toString();\n\n        switch (logType) {\n            case V: Log.v(tag, logStr);break;\n            case D: Log.d(tag, logStr);break;\n            case I: Log.i(tag, logStr);break;\n            case W: Log.w(tag, logStr);break;\n            case E: Log.e(tag, logStr);break;\n        }\n    }\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/tools/NetworkUtils.java",
    "content": "package me.shouheng.commons.tools;\n\nimport android.content.Context;\nimport android.net.ConnectivityManager;\nimport android.net.NetworkInfo;\n\n/**\n * Created by wangshouheng on 2017/2/26. */\npublic class NetworkUtils {\n\n    public static boolean isNetworkAvailable(Context context){\n        ConnectivityManager connectivityManager =\n                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);\n        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();\n        return ((networkInfo != null) && (networkInfo.isAvailable()));\n    }\n\n    public static boolean isWifi(Context mContext) {\n        ConnectivityManager connectivityManager =\n                (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);\n        NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();\n        return activeNetInfo != null && activeNetInfo.getType() == ConnectivityManager.TYPE_WIFI;\n    }\n}"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/tools/PalmUtils.java",
    "content": "package me.shouheng.commons.tools;\n\nimport android.app.Activity;\nimport android.graphics.drawable.Drawable;\nimport android.os.Build;\nimport androidx.annotation.ColorRes;\nimport androidx.annotation.DrawableRes;\nimport androidx.annotation.StringRes;\nimport androidx.fragment.app.Fragment;\n\nimport me.shouheng.commons.BaseApplication;\n\n/**\n * @author shouh\n * @version $Id: PalmUtils, v 0.1 2018/6/6 22:12 shouh Exp$\n */\npublic class PalmUtils {\n\n    // region API version utils\n    /**\n     * API 17\n     *\n     * @return true->above API 17 */\n    public static boolean isJellyBeanMR1() {\n        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1;\n    }\n\n    /**\n     * API 18\n     *\n     * @return true->above API 18 */\n    public static boolean isJellyBeanMR2() {\n        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2;\n    }\n\n    /**\n     * API 19\n     *\n     * @return true->above API 19 */\n    public static boolean isKitKat(){\n        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;\n    }\n\n    /**\n     * API 21\n     *\n     * @return true->above API 21 */\n    public static boolean isLollipop() {\n        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;\n    }\n\n    /**\n     * API 23\n     *\n     * @return true->above API 23 */\n    public static boolean isMarshmallow() {\n        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;\n    }\n\n    // endregion\n\n    // region judge alive\n    public static boolean isAlive(Activity activity) {\n        return activity != null && !activity.isFinishing() && !activity.isDestroyed();\n    }\n\n    public static boolean isAlive(Fragment fragment) {\n        return fragment != null && fragment.isAdded() && fragment.getActivity() != null && !fragment.getActivity().isFinishing();\n    }\n\n    public static boolean isAlive(android.app.Fragment fragment) {\n        return fragment != null && fragment.isAdded() && fragment.getActivity() != null && !fragment.getActivity().isFinishing();\n    }\n    // endregion\n\n    // region resources utils\n    public static int getColorCompact(@ColorRes int colorRes) {\n        return BaseApplication.getContext().getResources().getColor(colorRes);\n    }\n\n    public static String getStringCompact(@StringRes int stringRes) {\n        return BaseApplication.getContext().getResources().getString(stringRes);\n    }\n\n    public static Drawable getDrawableCompact(@DrawableRes int drawableRes) {\n        return BaseApplication.getContext().getResources().getDrawable(drawableRes);\n    }\n    // endregion\n\n    // region environment\n    public static String getPackageName(){\n        return BaseApplication.getContext().getApplicationContext().getPackageName();\n    }\n    // endregion\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/tools/StringUtils.java",
    "content": "package me.shouheng.commons.tools;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.StringRes;\nimport android.text.TextUtils;\n\nimport java.util.HashMap;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport me.shouheng.commons.BaseApplication;\n\n/**\n * @author shouh\n * @version $Id: StringUtils, v 0.1 2018/6/6 22:14 shouh Exp$\n */\npublic class StringUtils {\n\n    private static final String SEP1 = \"#\";\n\n    private static final String SEP2 = \"|\";\n\n    private static final String SEP3 = \"=\";\n\n    private static final Pattern VALID_EMAIL_ADDRESS_REGEX =\n            Pattern.compile(\"^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\\\.[A-Z]{2,6}$\", Pattern.CASE_INSENSITIVE);\n\n    private static final Pattern VALID_PHONE_REGEX =\n            Pattern.compile(\"(^(00){0,1}(13\\\\\\\\d|15[^4,\\\\\\\\D]|17[13678]|18\\\\\\\\d)\\\\\\\\d{8}|170[^346,\\\\\\\\D]\\\\\\\\d{7}$)\", Pattern.CASE_INSENSITIVE);\n\n    // region transfer string\n    public static String ListToString(List<?> list) {\n        StringBuilder sb = new StringBuilder();\n        if (list != null && list.size() > 0) {\n            for (int i = 0; i < list.size(); i++) {\n                if (list.get(i) == null || \"\".equals(list.get(i))) {\n                    continue;\n                }\n                // 如果值是list类型则调用自己\n                if (list.get(i) instanceof List) {\n                    sb.append(ListToString((List<?>) list.get(i)));\n                    sb.append(SEP1);\n                } else if (list.get(i) instanceof Map) {\n                    sb.append(MapToString((Map<?, ?>) list.get(i)));\n                    sb.append(SEP1);\n                } else {\n                    sb.append(list.get(i));\n                    sb.append(SEP1);\n                }\n            }\n        }\n        return \"L\" + sb.toString();\n    }\n\n    public static String MapToString(Map<?, ?> map) {\n        StringBuilder sb = new StringBuilder();\n        // 遍历map\n        for (Object obj : map.keySet()) {\n            if (obj == null) {\n                continue;\n            }\n            Object value = map.get(obj);\n            if (value instanceof List<?>) {\n                sb.append(obj.toString()).append(SEP1).append(ListToString((List<?>) value));\n                sb.append(SEP2);\n            } else if (value instanceof Map<?, ?>) {\n                sb.append(obj.toString()).append(SEP1).append(MapToString((Map<?, ?>) value));\n                sb.append(SEP2);\n            } else {\n                sb.append(obj.toString()).append(SEP3).append(value.toString());\n                sb.append(SEP2);\n            }\n        }\n        return \"M\" + sb.toString();\n    }\n\n    public static Map<String, Object> StringToMap(String mapText) {\n        if (mapText == null || mapText.equals(\"\")) return null;\n\n        mapText = mapText.substring(1);\n\n        Map<String, Object> map = new HashMap<>();\n        String[] text = mapText.split(\"\\\\\" + SEP2); // 转换为数组\n        for (String str : text) {\n            String[] keyText = str.split(SEP3); // 转换key与value的数组\n            if (keyText.length < 1) {\n                continue;\n            }\n            String key = keyText[0]; // key\n            String value = keyText[1]; // value\n            if (value.charAt(0) == 'M') {\n                Map<?, ?> map1 = StringToMap(value);\n                map.put(key, map1);\n            } else if (value.charAt(0) == 'L') {\n                List<?> list = StringToList(value);\n                map.put(key, list);\n            } else {\n                map.put(key, value);\n            }\n        }\n        return map;\n    }\n\n    public static List<Object> StringToList(String listText) {\n        if (listText == null || listText.equals(\"\")) {\n            return null;\n        }\n        listText = listText.substring(1);\n\n        List<Object> list = new LinkedList<>();\n        String[] text = listText.split(SEP1);\n        for (String str : text) {\n            if (str.charAt(0) == 'M') {\n                Map<?, ?> map = StringToMap(str);\n                list.add(map);\n            } else if (str.charAt(0) == 'L') {\n                List<?> lists = StringToList(str);\n                list.add(lists);\n            } else {\n                list.add(str);\n            }\n        }\n        return list;\n    }\n    // endregion\n\n    // region contnt checker\n    public static boolean isChinese(char c) {\n        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);\n        return ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS\n                || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS\n                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A\n                || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION\n                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION\n                || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS;\n    }\n\n    public static boolean isChinese(String strName) {\n        char[] ch = strName.toCharArray();\n        for (int i = 0; i < ch.length; i++) {\n            char c = ch[i];\n            if (isChinese(c)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    public static boolean hasNotChinese(String strName) {\n        if (!TextUtils.isEmpty(strName)) {\n            char[] ch = strName.toCharArray();\n            for (char c : ch) {\n                if (!isChinese(c)) {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n    public static boolean isNumeric(String str) {\n        Pattern pattern = Pattern.compile(\"[0-9]*\");\n        return pattern.matcher(str).matches();\n    }\n\n    public static boolean isEmail(String emailStr) {\n        Matcher matcher = VALID_EMAIL_ADDRESS_REGEX .matcher(emailStr);\n        return matcher.find();\n    }\n\n    public static boolean isPhoneNumber(@NonNull String phone) {\n        Matcher matcher = VALID_PHONE_REGEX .matcher(phone);\n        return matcher.find();\n    }\n    // endregion\n\n    // region safe parse\n    public static int parseInteger(String intString, int defaultValue) {\n        int number;\n        try {\n            number = TextUtils.isEmpty(intString) ? defaultValue : Integer.parseInt(intString);\n        } catch (NumberFormatException e) {\n            number = defaultValue;\n        }\n        return number;\n    }\n\n    public static double parseDouble(String intString, double defaultValue) {\n        double number;\n        try {\n            number = TextUtils.isEmpty(intString) ? defaultValue : Double.parseDouble(intString);\n        } catch (NumberFormatException e) {\n            number = defaultValue;\n        }\n        return number;\n    }\n    // endregion\n\n    // region format string\n    public static String formatString(@StringRes int stringRes, Object ...args) {\n        return String.format(getStringCompact(stringRes), args);\n    }\n    // endregion\n\n    // region resources utils\n    public static String getStringCompact(@StringRes int stringRes) {\n        return BaseApplication.getContext().getResources().getString(stringRes);\n    }\n    // endregion\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/tools/TimeUtils.java",
    "content": "package me.shouheng.commons.tools;\n\nimport android.content.Context;\nimport android.text.format.DateUtils;\n\nimport org.joda.time.DateTime;\nimport org.ocpsoft.prettytime.PrettyTime;\n\nimport java.text.SimpleDateFormat;\nimport java.util.Calendar;\nimport java.util.Date;\nimport java.util.Locale;\n\nimport me.shouheng.commons.BaseApplication;\n\n/**\n * @author shouh\n * @version $Id: TimeUtils, v 0.1 2018/6/6 22:14 shouh Exp$\n */\npublic class TimeUtils {\n\n    private static int daysOfMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};\n\n    public enum DateFormat {\n        YYYY_MMM_dd_E_hh_mm_a(\"yyyy MMM dd E hh:mm a\"),\n        YYYYMMdd_hh_mm_a(\"yyyy/MM/dd hh:mm a\"),\n        YYYYMMdd(\"yyyy/MM/dd\");\n\n        final String format;\n\n        DateFormat(String format) {\n            this.format = format;\n        }\n    }\n\n\n    // region 获取格式化的日期字符串\n    public static String formatDate(long millis, DateFormat dateFormat){\n        Date d = new Date(millis);\n        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat.format, Locale.getDefault());\n        return sdf.format(d);\n    }\n\n    public static String formatDate(Date date, DateFormat dateFormat) {\n        return date == null ? \"null\" : new SimpleDateFormat(dateFormat.format, Locale.getDefault()).format(date);\n    }\n\n    public static Date from(String strDate) {\n        return new DateTime(strDate).toDate();\n    }\n    // endregion\n\n\n    // region 获取指定时间格式的时间和日期字符串\n\n    /**\n     * 获取长的日期，比如2017年10月10日（后面有日）\n     *\n     * @param context 上下文\n     * @param date 日期\n     * @return 日期字符串 */\n    public static String getLongDate(Context context, Date date){\n        int flags = DateUtils.FORMAT_ABBREV_MONTH;\n        flags = flags | DateUtils.FORMAT_SHOW_YEAR;\n        return DateUtils.formatDateTime(context, date.getTime(), flags);\n    }\n\n    public static String getLongDateWithWeekday(Context context, Date date){\n        int flags = DateUtils.FORMAT_ABBREV_MONTH;\n        flags = flags | DateUtils.FORMAT_SHOW_YEAR;\n        return DateUtils.formatDateTime(context, date.getTime(), flags);\n    }\n\n    public static String getLongDateTime(Context context, Date date) {\n        return DateUtils.formatDateTime(context, date.getTime(),\n                DateUtils.FORMAT_NUMERIC_DATE\n                        | DateUtils.FORMAT_SHOW_TIME\n                        | DateUtils.FORMAT_SHOW_DATE\n                        | DateUtils.FORMAT_SHOW_YEAR);\n    }\n\n\n    public static String getShortDateWithWeekday(Context context, Calendar calendar) {\n        if (calendar == null) return \"\";\n        Calendar now = Calendar.getInstance();\n        int flags = DateUtils.FORMAT_ABBREV_MONTH;\n        if (calendar.get(Calendar.YEAR) != now.get(Calendar.YEAR)){\n            flags = flags | DateUtils.FORMAT_SHOW_YEAR;\n        }\n        return DateUtils.formatDateTime(context, calendar.getTime().getTime(), flags)\n                + new SimpleDateFormat(\" | E \", Locale.getDefault()).format(calendar.getTime());\n    }\n\n    /**\n     * 获取短的日期，如果指定的日期是今年的，就不用显示年份信息\n     *\n     * @param context 上下文\n     * @param calendar 日期\n     * @return 日期字符串 */\n    public static String getShortDate(Context context, Calendar calendar){\n        if (calendar == null) return \"\";\n        Calendar now = Calendar.getInstance();\n        int flags = DateUtils.FORMAT_ABBREV_MONTH;\n        if (calendar.get(Calendar.YEAR) != now.get(Calendar.YEAR)){\n            flags = flags | DateUtils.FORMAT_SHOW_YEAR;\n        }\n        return DateUtils.formatDateTime(context, calendar.getTime().getTime(), flags);\n    }\n\n    public static String getShortDate(Context context, Date date){\n        if (date == null) return \"\";\n        Calendar now = Calendar.getInstance();\n        Calendar c = Calendar.getInstance();\n        c.setTime(date);\n        int flags = DateUtils.FORMAT_ABBREV_MONTH;\n        if (c.get(Calendar.YEAR) != now.get(Calendar.YEAR)){\n            flags = flags | DateUtils.FORMAT_SHOW_YEAR;\n        }\n        return DateUtils.formatDateTime(context, date.getTime(), flags);\n    }\n\n    public static String getNoMonthDay(Context context, Date date) {\n        if (date == null) return \"\";\n        Calendar c = Calendar.getInstance();\n        c.setTime(date);\n        int flags = DateUtils.FORMAT_ABBREV_MONTH;\n        flags |= DateUtils.FORMAT_NO_MONTH_DAY;\n        flags = flags | DateUtils.FORMAT_SHOW_YEAR;\n        return DateUtils.formatDateTime(context, date.getTime(), flags);\n    }\n\n    /**\n     * 获取短的日期，日期规则同上，这里再加上时间\n     *\n     * @param mContext 上下文\n     * @param date 日期\n     * @return 日期字符串 */\n    public static String getDateTimeShort(Context mContext, Date date) {\n        if (date == null) return \"\";\n        Calendar now = Calendar.getInstance();\n        Calendar c = Calendar.getInstance();\n        c.setTime(date);\n        int flags = DateUtils.FORMAT_ABBREV_MONTH;\n        if (c.get(Calendar.YEAR) != now.get(Calendar.YEAR)){\n            flags = flags | DateUtils.FORMAT_SHOW_YEAR;\n        }\n        return DateUtils.formatDateTime(mContext, date.getTime(), flags) + \" \"\n                + DateUtils.formatDateTime(mContext, date.getTime(), DateUtils.FORMAT_SHOW_TIME);\n    }\n\n\n    /**\n     * 获取短的时间字符串\n     *\n     * @param context 上下文\n     * @param time 时间\n     * @return 时间字符串 */\n    public static String getShortTime(Context context, int time){\n        Calendar date = getTodayDate();\n        date.add(Calendar.MILLISECOND, time);\n        return getShortTime(context, date.getTime());\n    }\n\n    public static String getShortTime(Context context, int hour, int minute){\n        Calendar calendar = Calendar.getInstance();\n        calendar.set(Calendar.HOUR_OF_DAY, hour);\n        calendar.set(Calendar.MINUTE, minute);\n        return getShortTime(context, calendar.getTime());\n    }\n\n    public static String getShortTime(Context mContext, Date time){\n        return DateUtils.formatDateTime(mContext, time.getTime(), DateUtils.FORMAT_SHOW_TIME);\n    }\n\n\n    /**\n     * 获取相对于上次时间的距离的时间，比如2分钟之前\n     *\n     * @param date 日期\n     * @return 时间字符串 */\n    public static String getPrettyTime(Date date) {\n        if (date == null) {\n            return \"\";\n        }\n        return getPrettyTime(date, BaseApplication.getContext().getResources().getConfiguration().locale);\n    }\n\n    private static String getPrettyTime(Date date, Locale locale) {\n        if (date == null) {\n            return \"\";\n        }\n        PrettyTime pt = new PrettyTime();\n        if (locale != null) {\n            pt.setLocale(locale);\n        }\n        return pt.format(date);\n    }\n\n    // endregion\n\n\n    // region 获取某“月”的时间信息\n\n    /**\n     * 获取某个月的天数\n     *\n     * @param year 年\n     * @param month 1代表1月\n     * @return 天数 */\n    public static int getDaysOfMonth(int year, int month){\n        final int MONTHS_YEAR = 12;\n        if ((month<1) || (month>MONTHS_YEAR)){\n            return 0;\n        }\n        int days = daysOfMonth[month-1];\n        if ((month == 2) && isLeapYear(year)){\n            days++;\n        }\n        return days;\n    }\n\n    /**\n     * 获取指定月份的开始和截止的毫秒数：比如2017年5月，获取的是\n     * 2017年5月1日0:0:0 0'的毫秒数和2017年5月31日23:59:59 999'的毫秒数\n     *\n     * @param year 年\n     * @param month 1代表1月\n     * @return 开始和截止的毫秒数 */\n    public static long[] getStartAndEndMillisOfMonth(int year, int month){\n        Calendar startTime = Calendar.getInstance();\n        startTime.set(Calendar.YEAR, year);\n        startTime.set(Calendar.MONTH, month - 1);\n        startTime.set(Calendar.DAY_OF_MONTH, 1);\n        startTime.set(Calendar.HOUR_OF_DAY, 0);\n        startTime.set(Calendar.MINUTE, 0);\n        startTime.set(Calendar.SECOND, 0);\n        startTime.set(Calendar.MILLISECOND, 0);\n\n        int daysOfMonth = getDaysOfMonth(year, month);\n        Calendar endTime = (Calendar) startTime.clone();\n        endTime.add(Calendar.DAY_OF_MONTH, daysOfMonth);\n        return new long[]{startTime.getTimeInMillis(), endTime.getTimeInMillis() - 1};\n    }\n\n    // endregion\n\n\n    // region 获取某“周”的时间信息\n\n    /**\n     * 根据当前周历上的第一个可见的日期获取标题栏的子标题字符串\n     *\n     * @param newFirstVisibleDay 当前周历上的第一个可见的日期\n     * @param mNumberOfVisibleDays 日历上可见的日期\n     * @return 子标题字符串 */\n    public static String getWeekCalendarSubTitle(\n            Context context, Calendar newFirstVisibleDay, int mNumberOfVisibleDays){\n        if (mNumberOfVisibleDays == 1) {\n            return getShortDate(context, newFirstVisibleDay);\n        } else {\n            String str1 = getShortDate(context, newFirstVisibleDay);\n            newFirstVisibleDay.add(Calendar.DAY_OF_YEAR, mNumberOfVisibleDays - 1);\n            String str2 = getShortDate(context, newFirstVisibleDay);\n            return str1 + \"-\" + str2;\n        }\n    }\n\n    public static Calendar sevenDaysAgo() {\n        Calendar sevenDaysAgo = Calendar.getInstance();\n        sevenDaysAgo.set(Calendar.HOUR_OF_DAY, 0);\n        sevenDaysAgo.set(Calendar.MINUTE, 0);\n        sevenDaysAgo.set(Calendar.SECOND, 0);\n        sevenDaysAgo.set(Calendar.MILLISECOND, 0);\n        sevenDaysAgo.add(Calendar.DAY_OF_YEAR, -6);\n        return sevenDaysAgo;\n    }\n\n    // endregion\n\n\n    // region 获取某“日”的时间信息\n\n    /**\n     * 获取今天0时0分0秒0毫秒时的标准时间的毫秒数\n     *\n     * @return 毫秒数 */\n    public static long getMillisTodayStart(){\n        Calendar c = Calendar.getInstance();\n        c.set(Calendar.HOUR_OF_DAY, 0);\n        c.set(Calendar.MINUTE, 0);\n        c.set(Calendar.SECOND, 0);\n        c.set(Calendar.MILLISECOND, 0);\n        return c.getTimeInMillis();\n    }\n\n    /**\n     * 获取今天的23:59 59'999''的毫秒数\n     *\n     * @return 毫秒数 */\n    public static long getMillisTodayEnd() {\n        Calendar c = Calendar.getInstance();\n        c.set(Calendar.HOUR_OF_DAY, 23);\n        c.set(Calendar.MINUTE, 59);\n        c.set(Calendar.SECOND, 59);\n        c.set(Calendar.MILLISECOND, 999);\n        return c.getTimeInMillis();\n    }\n\n    /**\n     * 获取明天0时0分0秒0毫秒时的毫秒数\n     *\n     * @return 毫秒数 */\n    public static long getStandardMillisTomorrow(){\n        Calendar c = Calendar.getInstance();\n        c.set(Calendar.HOUR_OF_DAY, 0);\n        c.set(Calendar.MINUTE, 0);\n        c.set(Calendar.SECOND, 0);\n        c.set(Calendar.MILLISECOND, 0);\n        c.add(Calendar.DAY_OF_YEAR, 1);\n        return c.getTimeInMillis();\n    }\n\n    /**\n     * 获取指定日期的周次，周日(1)，周一(2)，周二(3)\n     *\n     * @param month 月，0为一月\n     * @return 周次 */\n    public static int getDayOfWeek(int year, int month, int day){\n        Calendar date = Calendar.getInstance();\n        date.set(Calendar.YEAR, year);\n        date.set(Calendar.MONTH, month);\n        date.set(Calendar.DAY_OF_MONTH, day);\n        return date.get(Calendar.DAY_OF_WEEK);\n    }\n\n    /**\n     * 获取指定日期的标准开始时间，指定日期的0时0分0秒的时间\n     *\n     * @return 日期 */\n    public static Date getStartDate(int year, int month, int day){\n        Calendar calendar = Calendar.getInstance();\n        calendar.set(Calendar.YEAR, year);\n        calendar.set(Calendar.MONTH, month);\n        calendar.set(Calendar.DAY_OF_MONTH, day);\n        calendar.set(Calendar.HOUR_OF_DAY, 0);\n        calendar.set(Calendar.MINUTE, 0);\n        calendar.set(Calendar.SECOND, 0);\n        calendar.set(Calendar.MILLISECOND, 0);\n        return calendar.getTime();\n    }\n\n    /**\n     * 获取指定日期的标准结束时间，23时59分59秒999毫秒\n     *\n     * @return 结束时间 */\n    public static Date getEndDate(int year, int month, int day){\n        Calendar calendar = Calendar.getInstance();\n        calendar.set(Calendar.YEAR, year);\n        calendar.set(Calendar.MONTH, month);\n        calendar.set(Calendar.DAY_OF_MONTH, day);\n        calendar.set(Calendar.HOUR_OF_DAY, 23);\n        calendar.set(Calendar.MINUTE, 59);\n        calendar.set(Calendar.SECOND, 59);\n        calendar.set(Calendar.MILLISECOND, 999);\n        return calendar.getTime();\n    }\n\n    // endregion\n\n\n    // region 获取今天、明天、本周五、本周日和下周一的标准时间\n\n    /**\n     * 获取今天的标准日期，小时5以后的单位的数值都是0\n     *\n     * @return  今天的Calendar对象，其中“天”之后的时间全部置为0 */\n    public static Calendar getTodayDate(){\n        final Calendar now = Calendar.getInstance();\n        now.set(Calendar.HOUR_OF_DAY, 0);\n        now.set(Calendar.MINUTE, 0);\n        now.set(Calendar.SECOND, 0);\n        now.set(Calendar.MILLISECOND, 0);\n        return now;\n    }\n\n    public static Calendar getTomorrowDate(){\n        final Calendar today = getTodayDate();\n        today.add(Calendar.DAY_OF_YEAR, 1);\n        return today;\n    }\n    // endregion\n\n\n    // region 其他的时间工具方法\n\n    /**\n     * 两个日期之间相距的天数\n     *\n     * @param start 开始日期\n     * @param end 结束日期\n     * @return 相距的天数 */\n    public static int daysSpan(Date start, Date end) {\n        return (int) ((end.getTime() - start.getTime()) / DateUtils.DAY_IN_MILLIS);\n    }\n\n    /**\n     * 录音时间的格式化\n     *\n     * @param recordMillis 录音时间（毫秒）\n     * @return 时间字符串 */\n    public static String getRecordTime(long recordMillis) {\n        int minute = (int) (recordMillis / DateUtils.MINUTE_IN_MILLIS);\n        int seconds = (int) ((recordMillis % DateUtils.MINUTE_IN_MILLIS ) / 1000);\n        String time = \"\";\n        if (minute < 10) {\n            time += \"0\" + minute;\n        } else {\n            time += minute;\n        }\n        time += \":\";\n        if (seconds < 10) {\n            time += \"0\" + seconds;\n        } else {\n            time += seconds;\n        }\n        return time;\n    }\n\n    /**\n     * 获取指定的起止毫秒之间的进度信息\n     *\n     * @param startMillis 开始的毫秒\n     * @param endMillis 结束的毫秒\n     * @return 真实进度 */\n    public static String getRealProgress(long startMillis, long endMillis){\n        long current = System.currentTimeMillis();\n        if (current > endMillis) return \"100%\";\n        if (current < startMillis) return \"0%\";\n        long pastedMillis = current - startMillis;\n        long spenMillis = endMillis - startMillis;\n        float progress = pastedMillis / (spenMillis * 1.0f);\n        return progress + \"%\";\n    }\n\n    public static int getHour(int timeMillis) {\n        return (int) (timeMillis / DateUtils.HOUR_IN_MILLIS);\n    }\n\n    public static int getMinute(int timeMillis) {\n        return (int) (timeMillis % DateUtils.HOUR_IN_MILLIS / DateUtils.MINUTE_IN_MILLIS);\n    }\n\n    public static int getTimeInMillis(int hour, int minute){\n        return (int) (DateUtils.HOUR_IN_MILLIS * hour + DateUtils.MINUTE_IN_MILLIS * minute);\n    }\n\n    public static String getTimeLength(Context context, long startMillis, long endMillis){\n        if (endMillis < startMillis) return \"--\";\n        long timeSpan = endMillis - startMillis;\n        int days = (int) (timeSpan / DateUtils.DAY_IN_MILLIS);\n        int hours = (int) (timeSpan % DateUtils.DAY_IN_MILLIS / DateUtils.HOUR_IN_MILLIS);\n        int minutes = (int) (timeSpan % DateUtils.DAY_IN_MILLIS % DateUtils.HOUR_IN_MILLIS / DateUtils.MINUTE_IN_MILLIS);\n        StringBuilder sb = new StringBuilder();\n        if (days != 0){\n            sb.append(String.valueOf(days));\n        }\n        if (hours != 0){\n            sb.append(String.valueOf(hours));\n        }\n        if (minutes != 0){\n            sb.append(String.valueOf(minutes));\n        }\n        return sb.toString();\n    }\n\n    /**\n     * 计算周历中需要滚动到的时间\n     *\n     * @return 要滚动到的时间 */\n    public static int calTimeToGo() {\n        Calendar calendar = Calendar.getInstance();\n        int current = calendar.get(Calendar.HOUR_OF_DAY);\n        current -= 3;\n        return current < 0 ? 0 : current;\n    }\n\n    // endregion\n\n\n    // region 农历相关的方法\n\n    /**\n     * 获取指定年的属相\n     *\n     * @param year 年\n     * @return 属相字符串 */\n    public static String getShuXiang(int year){\n        final String shuStrs[] = new String[]{\"鼠年\", \"牛年\", \"虎年\", \"兔年\",\n                \"龙年\", \"蛇年\", \"马年\", \"羊年\", \"猴年\", \"鸡年\", \"狗年\", \"猪年\"};\n        int x1 = year - 2008;\n        if (x1<0){\n            x1 = -x1;\n            int x2 = x1 % 12;\n            if (x2 == 0){\n                return shuStrs[0];\n            } else {\n                x2 = 12 - x2;\n                return shuStrs[x2];\n            }\n        } else{\n            int x2 = x1 % 12;\n            return shuStrs[x2];\n        }\n    }\n\n    /**\n     * 计算指定年份的干支\n     *\n     * @param year 年 */\n    public static String getGanZhi(int year){\n        final String[] ganStrs = new String[]{\"甲\", \"乙\", \"丙\", \"丁\", \"戊\", \"己\",\"庚\", \"辛\", \"壬\", \"癸\"};\n        final String[] zhiStrs = new String[]{\"子\", \"丑\", \"寅\", \"卯\", \"辰\", \"巳\",\"午\", \"未\", \"申\", \"酉\", \"戌\", \"亥\"};\n        String ganStr, zhiStr;\n        int sc = year-2000;\n        int gan = (7+sc)%10;\n        int zhi = (5+sc)%12;\n        if(gan<0){\n            gan+=10;\n        }\n        if(zhi<0){\n            zhi+=12;\n        }\n        if (gan == 0){\n            ganStr = ganStrs[9];\n        } else {\n            ganStr = ganStrs[gan-1];\n        }\n        if (zhi == 0){\n            zhiStr = zhiStrs[11];\n        } else {\n            zhiStr = zhiStrs[zhi-1];\n        }\n        return ganStr+zhiStr;\n    }\n\n    // endregion\n\n\n    private static boolean isLeapYear(int year){\n        return ((year%4 == 0) && (year%100 != 0))||(year%400 == 0);\n    }\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/tools/ToastUtils.java",
    "content": "package me.shouheng.commons.tools;\n\nimport androidx.annotation.StringRes;\nimport android.widget.Toast;\n\nimport me.shouheng.commons.BaseApplication;\n\npublic class ToastUtils {\n\n    private static Toast toast;\n\n    public static void makeToast(String msg) {\n        if (toast == null){\n            toast = Toast.makeText(BaseApplication.getContext(), msg, Toast.LENGTH_SHORT);\n            toast.show();\n        } else {\n            toast.setText(msg);\n            toast.show();\n        }\n    }\n\n    public static void makeToast(@StringRes int msgRes) {\n        if (toast == null){\n            toast = Toast.makeText(BaseApplication.getContext(), msgRes, Toast.LENGTH_SHORT);\n            toast.show();\n        } else {\n            toast.setText(msgRes);\n            toast.show();\n        }\n    }\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/tools/ViewUtils.java",
    "content": "package me.shouheng.commons.tools;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport android.content.res.Resources;\nimport android.graphics.Point;\nimport android.os.Build;\nimport androidx.annotation.FloatRange;\nimport android.util.DisplayMetrics;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.view.WindowManager;\nimport android.view.animation.AlphaAnimation;\n\nimport me.shouheng.commons.BaseApplication;\n\n/**\n * Created by Wang Shouheng on 2017/12/5. */\npublic class ViewUtils {\n\n    public static int getStatusBarHeight(Context context) {\n        int result = 0;\n        int resId = context.getResources().getIdentifier(\"status_bar_height\", \"dimen\", \"android\");\n        return resId > 0 ? context.getResources().getDimensionPixelOffset(resId) : result;\n    }\n\n    public static int dp2Px(float dpValues){\n        final float scale = getDisplayMetrics().density;\n        return (int)(dpValues * scale + 0.5f);\n    }\n\n    public static int sp2Px(float spValues){\n        final float fontScale = getDisplayMetrics().scaledDensity;\n        return (int)(spValues * fontScale + 0.5f);\n    }\n\n    public static DisplayMetrics getDisplayMetrics() {\n        return BaseApplication.getContext().getResources().getDisplayMetrics();\n    }\n\n    public static int getWindowWidth(Context context){\n        WindowManager window = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);\n        Point point = new Point();\n        window.getDefaultDisplay().getRealSize(point);\n        return point.x;\n    }\n\n    public static int getWindowHeight(Context context){\n        WindowManager window = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);\n        Point point = new Point();\n        window.getDefaultDisplay().getRealSize(point);\n        return point.y;\n    }\n\n    public static Point getWindowSize(Context context){\n        WindowManager window = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);\n        Point point = new Point();\n        window.getDefaultDisplay().getRealSize(point);\n        return point;\n    }\n\n    public static int getScreenOrientation(Context context) {\n        return context.getResources().getConfiguration().orientation;\n    }\n\n    public static int getStatusBarHeight(Resources r) {\n        int resourceId = r.getIdentifier(\"status_bar_height\", \"dimen\", \"android\");\n        if (resourceId > 0)\n            return r.getDimensionPixelSize(resourceId);\n        return 0;\n    }\n\n    public static View getRootView(Activity context) {\n        return ((ViewGroup) context.findViewById(android.R.id.content)).getChildAt(0);\n    }\n\n    public static void setAlpha(View v, @FloatRange(from = 0, to = 1) float alpha) {\n        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {\n            final AlphaAnimation animation = new AlphaAnimation(1F, alpha);\n            animation.setFillAfter(true);\n            v.startAnimation(animation);\n        } else {\n            v.setAlpha(alpha);\n        }\n    }\n\n    public static int getNavigationBarHeight(Context context) {\n        int navigationBarHeight = 0;\n        try {\n            Resources rs = context.getResources();\n            int id = rs.getIdentifier(\"navigation_bar_height\", \"dimen\", \"android\");\n            if (id > 0) {\n                navigationBarHeight = rs.getDimensionPixelSize(id);\n            }\n        } catch (Exception e) {\n            // default 0\n        }\n        return navigationBarHeight;\n    }\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/tools/glide/MyAppGlideModule.java",
    "content": "package me.shouheng.commons.tools.glide;\n\nimport android.content.Context;\n\nimport com.bumptech.glide.Glide;\nimport com.bumptech.glide.GlideBuilder;\nimport com.bumptech.glide.Registry;\nimport com.bumptech.glide.annotation.Excludes;\nimport com.bumptech.glide.annotation.GlideModule;\nimport com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader.Factory;\nimport com.bumptech.glide.load.engine.cache.InternalCacheDiskCacheFactory;\nimport com.bumptech.glide.load.model.GlideUrl;\nimport com.bumptech.glide.module.AppGlideModule;\n\nimport java.io.InputStream;\nimport java.util.concurrent.TimeUnit;\n\nimport androidx.annotation.NonNull;\nimport me.shouheng.commons.tools.LogUtils;\nimport okhttp3.Call;\nimport okhttp3.EventListener;\nimport okhttp3.OkHttpClient;\n\n/**\n * @author shouh\n * @version $Id: MyAppGlideModule, v 0.1 2018/7/29 18:53 shouh Exp$\n */\n@GlideModule\n@Excludes(value = {com.bumptech.glide.integration.okhttp3.OkHttpLibraryGlideModule.class})\npublic class MyAppGlideModule extends AppGlideModule {\n\n    private static final String DISK_CACHE_DIR = \"Glide_cache\";\n\n    private static final long DISK_CACHE_SIZE = 100 << 20; // 100M\n\n    @Override\n    public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {\n        builder.setDiskCache(new InternalCacheDiskCacheFactory(context, DISK_CACHE_DIR, DISK_CACHE_SIZE));\n    }\n\n    @Override\n    public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {\n        OkHttpClient okHttpClient = new OkHttpClient.Builder()\n                .connectTimeout(10, TimeUnit.SECONDS)\n                .writeTimeout(10, TimeUnit.SECONDS)\n                .readTimeout(15, TimeUnit.SECONDS)\n                .eventListener(new EventListener() {\n                    @Override\n                    public void callStart(Call call) {\n                        // 输出日志，用于确认使用了我们配置的 OkHttp 进行网络请求\n                        LogUtils.d(call.request().url().toString());\n                    }\n                })\n                .build();\n        registry.replace(GlideUrl.class, InputStream.class, new Factory(okHttpClient));\n    }\n\n    @Override\n    public boolean isManifestParsingEnabled() {\n        // 不使用 Manifest 中的 GlideModule\n        return false;\n    }\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/tools/permission/OnGetPermissionCallback.java",
    "content": "package me.shouheng.commons.tools.permission;\n\n/**\n * Created by WngShhng on 2018/6/7.*/\npublic interface OnGetPermissionCallback {\n    void onGetPermission();\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/tools/permission/PermissionUtils.java",
    "content": "package me.shouheng.commons.tools.permission;\n\nimport android.Manifest;\nimport android.annotation.TargetApi;\nimport android.content.Context;\nimport android.content.pm.PackageManager;\nimport android.os.Build;\nimport androidx.annotation.NonNull;\nimport androidx.core.app.ActivityCompat;\nimport androidx.core.content.ContextCompat;\n\nimport me.shouheng.commons.R;\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.view.activity.BaseActivity;\n\n/**\n * Created by wang shouheng on 2017/12/5.*/\npublic class PermissionUtils {\n\n    public static <T extends BaseActivity> void checkStoragePermission(@NonNull T activity, OnGetPermissionCallback callback) {\n        checkPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE, BaseConstants.REQUEST_PERMISSION_STORAGE, callback);\n    }\n\n    public static <T extends BaseActivity> void checkPhonePermission(@NonNull T activity, OnGetPermissionCallback callback){\n        checkPermission(activity, Manifest.permission.READ_PHONE_STATE, BaseConstants.REQUEST_PERMISSION_PHONE_STATE, callback);\n    }\n\n    public static <T extends BaseActivity> void checkLocationPermission(@NonNull T activity, OnGetPermissionCallback callback){\n        checkPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION, BaseConstants.REQUEST_PERMISSION_LOCATION, callback);\n    }\n\n    public static <T extends BaseActivity> void checkRecordPermission(@NonNull T activity, OnGetPermissionCallback callback){\n        checkPermission(activity, Manifest.permission.RECORD_AUDIO, BaseConstants.REQUEST_PERMISSION_MICROPHONE, callback);\n    }\n\n    public static <T extends BaseActivity> void checkSmsPermission(@NonNull T activity, OnGetPermissionCallback callback) {\n        checkPermission(activity, Manifest.permission.SEND_SMS, BaseConstants.REQUEST_PERMISSION_SMS, callback);\n    }\n\n    @TargetApi(Build.VERSION_CODES.KITKAT_WATCH)\n    public static <T extends BaseActivity> void checkSensorsPermission(@NonNull T activity, OnGetPermissionCallback callback) {\n        checkPermission(activity, Manifest.permission.BODY_SENSORS, BaseConstants.REQUEST_PERMISSION_SENSORS, callback);\n    }\n\n    public static <T extends BaseActivity> void checkContactsPermission(@NonNull T activity, OnGetPermissionCallback callback) {\n        checkPermission(activity, Manifest.permission.READ_CONTACTS, BaseConstants.REQUEST_PERMISSION_CONTACTS, callback);\n    }\n\n    public static <T extends BaseActivity> void checkCameraPermission(@NonNull T activity, OnGetPermissionCallback callback) {\n        checkPermission(activity, Manifest.permission.CAMERA, BaseConstants.REQUEST_PERMISSION_CAMERA, callback);\n    }\n\n    public static <T extends BaseActivity> void checkCalendarPermission(@NonNull T activity, OnGetPermissionCallback callback) {\n        checkPermission(activity, Manifest.permission.READ_CALENDAR, BaseConstants.REQUEST_PERMISSION_CALENDAR, callback);\n    }\n\n    private static <T extends BaseActivity> void checkPermission(@NonNull T activity, @NonNull String permission, int requestCode, OnGetPermissionCallback callback) {\n        activity.setOnGetPermissionCallback(callback);\n        if (ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {\n            ActivityCompat.requestPermissions(activity, new String[]{permission}, requestCode);\n        } else {\n            if (callback != null) {\n                callback.onGetPermission();\n            }\n        }\n    }\n\n    public static String getPermissionName(Context context, int requestCode) {\n        switch (requestCode){\n            case BaseConstants.REQUEST_PERMISSION_STORAGE:\n                return context.getString(R.string.permission_storage_permission);\n            case BaseConstants.REQUEST_PERMISSION_LOCATION:\n                return context.getString(R.string.permission_location_permission);\n            case BaseConstants.REQUEST_PERMISSION_MICROPHONE:\n                return context.getString(R.string.permission_microphone_permission);\n            case BaseConstants.REQUEST_PERMISSION_PHONE_STATE:\n                return context.getString(R.string.permission_phone_permission);\n            case BaseConstants.REQUEST_PERMISSION_SMS:\n                return context.getString(R.string.permission_sms_permission);\n            case BaseConstants.REQUEST_PERMISSION_SENSORS:\n                return context.getString(R.string.permission_sensor_permission);\n            case BaseConstants.REQUEST_PERMISSION_CONTACTS:\n                return context.getString(R.string.permission_contacts_permission);\n            case BaseConstants.REQUEST_PERMISSION_CAMERA:\n                return context.getString(R.string.permission_camera_permission);\n            case BaseConstants.REQUEST_PERMISSION_CALENDAR:\n                return context.getString(R.string.permission_calendar_permission);\n        }\n        return context.getString(R.string.permission_default_permission_name);\n    }\n}"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/tools/theme/SystemUiVisibilityUtil.java",
    "content": "package me.shouheng.commons.tools.theme;\n\nimport android.annotation.TargetApi;\nimport android.app.Activity;\nimport android.os.Build;\nimport android.view.View;\n\nimport me.shouheng.commons.tools.PalmUtils;\n\n@TargetApi(Build.VERSION_CODES.KITKAT)\npublic class SystemUiVisibilityUtil {\n\n    private static final int FLAG_IMMERSIVE = View.SYSTEM_UI_FLAG_IMMERSIVE // 与SYSTEM_UI_FLAG_HIDE_NAVIGATION组合使用，没有设置的话在隐藏导航栏后将没有交互\n            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // 隐藏虚拟按键(导航栏)\n            | View.SYSTEM_UI_FLAG_FULLSCREEN; // Activity全屏显示，且状态栏被隐藏覆盖掉\n\n    @TargetApi(17)\n    private final static int FLAG_VISIBILITY_17 = View.SYSTEM_UI_FLAG_LAYOUT_STABLE\n            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION\n            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN\n            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar\n            | View.SYSTEM_UI_FLAG_FULLSCREEN;\n\n    @TargetApi(19)\n    private final static int FLAG_VISIBILITY_19 = FLAG_VISIBILITY_17 // hide status bar\n            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY\n            | View.SYSTEM_UI_FLAG_IMMERSIVE;\n\n    public static int getSystemVisibility() {\n        if (PalmUtils.isLollipop()) {\n            return FLAG_VISIBILITY_19;\n        } else {\n            return FLAG_VISIBILITY_17;\n        }\n    }\n\n    public static void exit(Activity activity) {\n        if (Build.VERSION.SDK_INT >= 19) {\n            addFlags(activity.getWindow().getDecorView(), FLAG_IMMERSIVE);\n        }\n    }\n\n    private static void addFlags(View decorView, int flags) {\n        decorView.setSystemUiVisibility(decorView.getSystemUiVisibility() | flags);\n    }\n\n    public static void enter(Activity activity) {\n        if (Build.VERSION.SDK_INT >= 19) {\n            clearFlags(activity.getWindow().getDecorView(), FLAG_IMMERSIVE);\n        }\n    }\n\n    private static void clearFlags(View view, int flags) {\n        view.setSystemUiVisibility(view.getSystemUiVisibility() & ~flags);\n        // & ~flags 清除view.getSystemUiVisibility()中的flags\n    }\n}\n\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/tools/theme/ThemeUtils.java",
    "content": "package me.shouheng.commons.tools.theme;\n\nimport android.annotation.TargetApi;\nimport android.app.Activity;\nimport android.graphics.Color;\nimport android.os.Build;\nimport androidx.annotation.ColorInt;\nimport android.view.View;\nimport android.view.WindowManager;\n\nimport me.shouheng.commons.R;\nimport me.shouheng.commons.tools.PalmUtils;\n\n/**\n * @author shouh\n * @version $Id: ThemeUtils, v 0.1 2018/6/7 22:10 shouh Exp$\n */\npublic class ThemeUtils {\n\n    /**\n     * should use colored status bar */\n    private final static boolean useThemeStatusBarColor = false;\n\n    /**\n     * status text and image style, true use dark, false light */\n    private final static boolean useStatusBarColor = false;\n\n    public static void customStatusBar(Activity activity) {\n        // 5.0 and above\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {\n            View decorView = activity.getWindow().getDecorView();\n            int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;\n            decorView.setSystemUiVisibility(option);\n            if (useThemeStatusBarColor) {\n                activity.getWindow().setStatusBarColor(PalmUtils.getColorCompact(R.color.colorPrimaryDark));\n            } else {\n                activity.getWindow().setStatusBarColor(Color.TRANSPARENT);\n            }\n        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {\n            // 4.4 to 5.0\n            WindowManager.LayoutParams localLayoutParams = activity.getWindow().getAttributes();\n            localLayoutParams.flags = (WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | localLayoutParams.flags);\n        }\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !useStatusBarColor) {\n            activity.getWindow().getDecorView().setSystemUiVisibility(\n                    View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);\n        }\n    }\n\n    @TargetApi(Build.VERSION_CODES.LOLLIPOP)\n    public static void setStatusBarColor(Activity activity, @ColorInt int color) {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {\n            activity.getWindow().setStatusBarColor(color);\n        }\n    }\n\n    public static void hideSystemUI(Activity activity) {\n        activity.runOnUiThread(() -> activity.getWindow().getDecorView().setSystemUiVisibility(\n                SystemUiVisibilityUtil.getSystemVisibility()));\n    }\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/view/activity/BaseActivity.java",
    "content": "package me.shouheng.commons.view.activity;\n\nimport android.content.Intent;\nimport android.content.pm.PackageManager;\nimport android.net.Uri;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.provider.Settings;\nimport androidx.annotation.NonNull;\nimport androidx.appcompat.app.AlertDialog;\nimport androidx.appcompat.app.AppCompatActivity;\n\nimport me.shouheng.commons.R;\nimport me.shouheng.commons.tools.permission.OnGetPermissionCallback;\nimport me.shouheng.commons.tools.PalmUtils;\nimport me.shouheng.commons.tools.permission.PermissionUtils;\nimport me.shouheng.commons.tools.theme.ThemeUtils;\nimport me.shouheng.commons.tools.ToastUtils;\n\n/**\n * Created by WngShhng on 2018/6/7.\n */\npublic abstract class BaseActivity extends AppCompatActivity {\n\n    private OnGetPermissionCallback onGetPermissionCallback;\n\n    public void setOnGetPermissionCallback(OnGetPermissionCallback onGetPermissionCallback) {\n        this.onGetPermissionCallback = onGetPermissionCallback;\n    }\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        ThemeUtils.customStatusBar(this);\n    }\n\n    @Override\n    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {\n        super.onRequestPermissionsResult(requestCode, permissions, grantResults);\n        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){\n            if (onGetPermissionCallback != null){\n                onGetPermissionCallback.onGetPermission();\n            }\n        } else {\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){\n                // Add array length check logic to avoid ArrayIndexOutOfBoundsException\n                if (permissions.length > 0 && !shouldShowRequestPermissionRationale(permissions[0])){\n                    showPermissionSettingDialog(requestCode);\n                } else {\n                    ToastUtils.makeToast(getToastMessage(requestCode));\n                }\n            } else {\n                ToastUtils.makeToast(getToastMessage(requestCode));\n            }\n        }\n    }\n\n    private void showPermissionSettingDialog(int requestCode) {\n        String permissionName = PermissionUtils.getPermissionName(this, requestCode);\n        String msg = String.format(getString(R.string.set_permission_in_setting), permissionName);\n        new AlertDialog.Builder(this)\n                .setTitle(R.string.setting_permission)\n                .setMessage(msg)\n                .setPositiveButton(R.string.to_set, (dialog, which) -> toSetPermission())\n                .setNegativeButton(R.string.cancel, null)\n                .create()\n                .show();\n    }\n\n    private void toSetPermission() {\n        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);\n        Uri uri = Uri.fromParts(\"package\", PalmUtils.getPackageName(), null);\n        intent.setData(uri);\n        startActivity(intent);\n    }\n\n    /**\n     * Get the permission toast message according to request code. If the permission name can be found,\n     * we will show the permission name in the message, otherwise show the default message.\n     *\n     * @param requestCode the request code\n     * @return the message to toast */\n    private String getToastMessage(int requestCode) {\n        String permissionName = PermissionUtils.getPermissionName(this, requestCode);\n        String defName = getString(R.string.permission_default_permission_name);\n        if (defName.equals(permissionName)) {\n            return getString(R.string.permission_denied_try_again_after_set);\n        } else {\n            return String.format(getString(R.string.permission_denied_try_again_after_set_given_permission), permissionName);\n        }\n    }\n\n    public BaseActivity getContext() {\n        return this;\n    }\n}\n\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/view/activity/CommonActivity.java",
    "content": "package me.shouheng.commons.view.activity;\n\nimport android.app.Activity;\nimport androidx.lifecycle.ViewModel;\nimport androidx.lifecycle.ViewModelProviders;\nimport android.content.Intent;\nimport androidx.databinding.DataBindingUtil;\nimport androidx.databinding.ViewDataBinding;\nimport android.os.Bundle;\nimport androidx.annotation.IdRes;\nimport androidx.annotation.NonNull;\nimport androidx.fragment.app.Fragment;\n\nimport io.reactivex.disposables.Disposable;\nimport io.reactivex.functions.Consumer;\nimport me.shouheng.commons.rxbus.RxBus;\nimport me.shouheng.commons.tools.LogUtils;\n\n/**\n * Created by WngShhng on 2018/5/18.*/\npublic abstract class CommonActivity<T extends ViewDataBinding> extends UMengActivity {\n\n    private T binding;\n\n    protected abstract int getLayoutResId();\n\n    protected abstract void doCreateView(Bundle savedInstanceState);\n\n    protected void beforeCreate(Bundle savedInstanceState) { }\n\n    @Override\n    protected final void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n\n        beforeCreate(savedInstanceState);\n\n        if (getLayoutResId() <= 0 ) {\n            throw new AssertionError(\"Subclass must provide a valid layout resource id\");\n        }\n\n        binding = DataBindingUtil.inflate(getLayoutInflater(), getLayoutResId(), null, false);\n\n        setContentView(binding.getRoot());\n\n        doCreateView(savedInstanceState);\n    }\n\n    protected final T getBinding() {\n        return binding;\n    }\n\n    protected <VM extends ViewModel> VM getViewModel(@NonNull Class<VM> modelClass) {\n        return ViewModelProviders.of(this).get(modelClass);\n    }\n\n    protected Fragment getCurrentFragment(@IdRes int resId) {\n        return getSupportFragmentManager().findFragmentById(resId);\n    }\n\n    public void startActivity(Class<? extends Activity> activity) {\n        startActivity(new Intent(this, activity));\n    }\n\n    public void startActivityForResult(Class<? extends Activity> activity, int requestCode) {\n        startActivityForResult(new Intent(this, activity), requestCode);\n    }\n\n    /**\n     * Used to call {@link #onBackPressed()} to avoid override by sub class */\n    public void superOnBackPressed() {\n        super.onBackPressed();\n    }\n\n    protected void postEvent(Object object) {\n        RxBus.getRxBus().post(object);\n    }\n\n    protected <M> void addSubscription(Class<M> eventType, Consumer<M> action) {\n        Disposable disposable = RxBus.getRxBus().doSubscribe(eventType, action, LogUtils::d);\n        RxBus.getRxBus().addSubscription(this, disposable);\n    }\n\n    protected <M> void addSubscription(Class<M> eventType, Consumer<M> action, Consumer<Throwable> error) {\n        Disposable disposable = RxBus.getRxBus().doSubscribe(eventType, action, error);\n        RxBus.getRxBus().addSubscription(this, disposable);\n    }\n\n    @Override\n    protected void onDestroy() {\n        super.onDestroy();\n        RxBus.getRxBus().unSubscribe(this);\n    }\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/view/activity/CommonDaggerActivity.java",
    "content": "package me.shouheng.commons.view.activity;\n\nimport androidx.databinding.ViewDataBinding;\nimport android.os.Bundle;\n\nimport dagger.android.AndroidInjection;\n\n/**\n * @author shouh\n * @version $Id: CommonDaggerActivity, v 0.1 2018/6/6 22:46 shouh Exp$\n */\npublic abstract class CommonDaggerActivity<T extends ViewDataBinding> extends CommonActivity<T> {\n\n    @Override\n    protected void beforeCreate(Bundle savedInstanceState) {\n        AndroidInjection.inject(this);\n    }\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/view/activity/UMengActivity.java",
    "content": "package me.shouheng.commons.view.activity;\n\nimport android.os.Bundle;\n\nimport com.umeng.message.PushAgent;\n\n/**\n * @author WngShhng (shouheng2015@gmail.com)\n * @version $Id: UMengActivity, v 0.1 2018/12/26 23:47 shouh Exp$\n */\npublic class UMengActivity extends BaseActivity {\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        PushAgent.getInstance(this).onAppStart();\n    }\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/view/fragment/CommonDaggerFragment.java",
    "content": "package me.shouheng.commons.view.fragment;\n\nimport androidx.lifecycle.LifecycleRegistry;\nimport androidx.lifecycle.LifecycleRegistryOwner;\nimport androidx.databinding.ViewDataBinding;\nimport android.os.Bundle;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport dagger.android.support.AndroidSupportInjection;\n\n/**\n * @author shouh\n * @version $Id: CommonDaggerFragment, v 0.1 2018/6/9 13:40 shouh Exp$\n */\npublic abstract class CommonDaggerFragment<T extends ViewDataBinding> extends CommonFragment<T> implements LifecycleRegistryOwner {\n\n    private LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);\n\n    @Override\n    public void onCreate(@Nullable Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        AndroidSupportInjection.inject(this);\n    }\n\n    @Override\n    @NonNull\n    public LifecycleRegistry getLifecycle() {\n        return lifecycleRegistry;\n    }\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/view/fragment/CommonFragment.java",
    "content": "package me.shouheng.commons.view.fragment;\n\nimport android.annotation.TargetApi;\nimport android.app.Activity;\nimport androidx.databinding.DataBindingUtil;\nimport androidx.databinding.ViewDataBinding;\nimport android.os.Build;\nimport android.os.Bundle;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.fragment.app.Fragment;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\n\nimport io.reactivex.disposables.Disposable;\nimport io.reactivex.functions.Consumer;\nimport me.shouheng.commons.rxbus.RxBus;\nimport me.shouheng.commons.tools.LogUtils;\nimport me.shouheng.commons.view.activity.CommonActivity;\n\n/**\n * Created by wang shouheng on 2017/12/23. */\npublic abstract class CommonFragment<T extends ViewDataBinding> extends Fragment {\n\n    private T binding;\n\n    protected abstract int getLayoutResId();\n\n    protected abstract void doCreateView(Bundle savedInstanceState);\n\n    private View rootView;\n\n    @Override\n    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {\n\n        if (rootView != null) {\n            return rootView;\n        }\n\n        if (getLayoutResId() <= 0 ) {\n            throw new AssertionError(\"Subclass must provide a valid layout resource id\");\n        }\n\n        binding = DataBindingUtil.inflate(inflater, getLayoutResId(), container, false);\n\n        doCreateView(savedInstanceState);\n\n        return rootView = binding.getRoot();\n    }\n\n    protected View getRoot() {\n        return binding.getRoot();\n    }\n\n    protected final T getBinding() {\n        return binding;\n    }\n\n    @TargetApi(Build.VERSION_CODES.LOLLIPOP)\n    protected void setStatusBarColor(int color) {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && getActivity() != null) {\n            getActivity().getWindow().setStatusBarColor(color);\n        }\n    }\n\n    public void onBackPressed() {\n        Activity activity = getActivity();\n        if (activity instanceof CommonActivity) {\n            ((CommonActivity) activity).superOnBackPressed();\n        }\n    }\n\n    protected void postEvent(Object object) {\n        RxBus.getRxBus().post(object);\n    }\n\n    protected <M> void addSubscription(Class<M> eventType, Consumer<M> action) {\n        Disposable disposable = RxBus.getRxBus().doSubscribe(eventType, action, LogUtils::d);\n        RxBus.getRxBus().addSubscription(this, disposable);\n    }\n\n    protected <M> void addSubscription(Class<M> eventType, Consumer<M> action, Consumer<Throwable> error) {\n        Disposable disposable = RxBus.getRxBus().doSubscribe(eventType, action, error);\n        RxBus.getRxBus().addSubscription(this, disposable);\n    }\n\n    @Override\n    public void onDestroy() {\n        super.onDestroy();\n        RxBus.getRxBus().unSubscribe(this);\n    }\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/view/widget/CircleImageView.java",
    "content": "package me.shouheng.commons.view.widget;\n\nimport android.content.Context;\nimport android.content.res.TypedArray;\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapShader;\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.graphics.ColorFilter;\nimport android.graphics.Matrix;\nimport android.graphics.Paint;\nimport android.graphics.RectF;\nimport android.graphics.Shader;\nimport android.graphics.drawable.BitmapDrawable;\nimport android.graphics.drawable.ColorDrawable;\nimport android.graphics.drawable.Drawable;\nimport android.net.Uri;\nimport androidx.annotation.ColorRes;\nimport androidx.annotation.DrawableRes;\nimport androidx.core.content.ContextCompat;\nimport androidx.appcompat.widget.AppCompatImageView;\nimport android.util.AttributeSet;\n\nimport me.shouheng.commons.R;\n\n\npublic class CircleImageView extends AppCompatImageView {\n\n    private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;\n\n    private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;\n    private static final int COLORDRAWABLE_DIMENSION = 2;\n\n    private static final int DEFAULT_BORDER_WIDTH = 0;\n    private static final int DEFAULT_BORDER_COLOR = Color.BLACK;\n    private static final boolean DEFAULT_BORDER_OVERLAY = false;\n\n    private final RectF mDrawableRect = new RectF();\n    private final RectF mBorderRect = new RectF();\n\n    private final Matrix mShaderMatrix = new Matrix();\n    private final Paint mBitmapPaint = new Paint();\n    private final Paint mBorderPaint = new Paint();\n\n    private int mBorderColor = DEFAULT_BORDER_COLOR;\n    private int mBorderWidth = DEFAULT_BORDER_WIDTH;\n\n    private Bitmap mBitmap;\n    private BitmapShader mBitmapShader;\n    private int mBitmapWidth;\n    private int mBitmapHeight;\n\n    private float mDrawableRadius;\n    private float mBorderRadius;\n\n    private ColorFilter mColorFilter;\n\n    private boolean mReady;\n    private boolean mSetupPending;\n    private boolean mBorderOverlay;\n\n    private boolean isFillingColor;\n\n    public CircleImageView(Context context) {\n        super(context);\n\n        init();\n    }\n\n    public CircleImageView(Context context, AttributeSet attrs) {\n        this(context, attrs, 0);\n    }\n\n    public CircleImageView(Context context, AttributeSet attrs, int defStyle) {\n        super(context, attrs, defStyle);\n\n        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0);\n\n        mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_border_width, DEFAULT_BORDER_WIDTH);\n        mBorderColor = a.getColor(R.styleable.CircleImageView_border_color, DEFAULT_BORDER_COLOR);\n        mBorderOverlay = a.getBoolean(R.styleable.CircleImageView_border_overlay, DEFAULT_BORDER_OVERLAY);\n\n        a.recycle();\n\n        init();\n    }\n\n    private void init() {\n        super.setScaleType(SCALE_TYPE);\n        mReady = true;\n\n        if (mSetupPending) {\n            setup();\n            mSetupPending = false;\n        }\n    }\n\n    @Override\n    public ScaleType getScaleType() {\n        return SCALE_TYPE;\n    }\n\n    @Override\n    public void setScaleType(ScaleType scaleType) {\n        if (scaleType != SCALE_TYPE) {\n            throw new IllegalArgumentException(String.format(\"ScaleType %s not supported.\", scaleType));\n        }\n    }\n\n    @Override\n    public void setAdjustViewBounds(boolean adjustViewBounds) {\n        if (adjustViewBounds) {\n            throw new IllegalArgumentException(\"adjustViewBounds not supported.\");\n        }\n    }\n\n    @Override\n    protected void onDraw(Canvas canvas) {\n        /* 修改这里的设置，以使得该组件能够支持直接使用整型颜色绘制圆形 */\n        if (isFillingColor) {\n            mDrawableRadius = Math.min(getWidth()/2, getHeight()/2);\n        } else if (getDrawable() == null) {\n            return;\n        }\n        canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius, mBitmapPaint);\n        if (mBorderWidth != 0) canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius, mBorderPaint);\n    }\n\n    @Override\n    protected void onSizeChanged(int w, int h, int oldw, int oldh) {\n        super.onSizeChanged(w, h, oldw, oldh);\n        setup();\n    }\n\n    public int getBorderColor() {\n        return mBorderColor;\n    }\n\n    public void setBorderColor(int borderColor) {\n        if (borderColor == mBorderColor) {\n            return;\n        }\n\n        mBorderColor = borderColor;\n        mBorderPaint.setColor(mBorderColor);\n        invalidate();\n    }\n\n    public void setBorderColorResource(@ColorRes int borderColorRes) {\n        setBorderColor(ContextCompat.getColor(getContext(), borderColorRes));\n    }\n\n    public int getBorderWidth() {\n        return mBorderWidth;\n    }\n\n    public void setBorderWidth(int borderWidth) {\n        if (borderWidth == mBorderWidth) {\n            return;\n        }\n\n        mBorderWidth = borderWidth;\n        setup();\n    }\n\n    public boolean isBorderOverlay() {\n        return mBorderOverlay;\n    }\n\n    public void setBorderOverlay(boolean borderOverlay) {\n        if (borderOverlay == mBorderOverlay) {\n            return;\n        }\n\n        mBorderOverlay = borderOverlay;\n        setup();\n    }\n\n    @Override\n    public void setImageBitmap(Bitmap bm) {\n        super.setImageBitmap(bm);\n        mBitmap = bm;\n        setup();\n    }\n\n    @Override\n    public void setImageDrawable(Drawable drawable) {\n        super.setImageDrawable(drawable);\n        mBitmap = getBitmapFromDrawable(drawable);\n        setup();\n    }\n\n    @Override\n    public void setImageResource(@DrawableRes int resId) {\n        super.setImageResource(resId);\n        mBitmap = getBitmapFromDrawable(getDrawable());\n        setup();\n    }\n\n    /* 使用填充的颜色绘制圆形，这里使用了一个标记，以不影响该组件之前的性能 */\n    public void setFillingCircleColor(int color) {\n        mBitmapPaint.setColor(color);\n        mBitmapPaint.setAntiAlias(true);\n        isFillingColor = true;\n        invalidate();\n    }\n\n    @Override\n    public void setImageURI(Uri uri) {\n        super.setImageURI(uri);\n        mBitmap = getBitmapFromDrawable(getDrawable());\n        setup();\n    }\n\n    @Override\n    public void setColorFilter(ColorFilter cf) {\n        if (cf == mColorFilter) {\n            return;\n        }\n\n        mColorFilter = cf;\n        mBitmapPaint.setColorFilter(mColorFilter);\n        invalidate();\n    }\n\n    private Bitmap getBitmapFromDrawable(Drawable drawable) {\n        if (drawable == null) {\n            return null;\n        }\n\n        if (drawable instanceof BitmapDrawable) {\n            return ((BitmapDrawable) drawable).getBitmap();\n        }\n\n        try {\n            Bitmap bitmap;\n\n            if (drawable instanceof ColorDrawable) {\n                bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);\n            } else {\n                bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);\n            }\n\n            Canvas canvas = new Canvas(bitmap);\n            drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());\n            drawable.draw(canvas);\n            return bitmap;\n        } catch (OutOfMemoryError e) {\n            return null;\n        }\n    }\n\n    private void setup() {\n        if (!mReady) {\n            mSetupPending = true;\n            return;\n        }\n\n        if (mBitmap == null) {\n            return;\n        }\n\n        mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);\n\n        mBitmapPaint.setAntiAlias(true);\n        mBitmapPaint.setShader(mBitmapShader);\n\n        mBorderPaint.setStyle(Paint.Style.STROKE);\n        mBorderPaint.setAntiAlias(true);\n        mBorderPaint.setColor(mBorderColor);\n        mBorderPaint.setStrokeWidth(mBorderWidth);\n\n        mBitmapHeight = mBitmap.getHeight();\n        mBitmapWidth = mBitmap.getWidth();\n\n        mBorderRect.set(0, 0, getWidth(), getHeight());\n        mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2, (mBorderRect.width() - mBorderWidth) / 2);\n\n        mDrawableRect.set(mBorderRect);\n        if (!mBorderOverlay) {\n            mDrawableRect.inset(mBorderWidth, mBorderWidth);\n        }\n        mDrawableRadius = Math.min(mDrawableRect.height() / 2, mDrawableRect.width() / 2);\n\n        updateShaderMatrix();\n        invalidate();\n    }\n\n    private void updateShaderMatrix() {\n        float scale;\n        float dx = 0;\n        float dy = 0;\n\n        mShaderMatrix.set(null);\n\n        if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {\n            scale = mDrawableRect.height() / (float) mBitmapHeight;\n            dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;\n        } else {\n            scale = mDrawableRect.width() / (float) mBitmapWidth;\n            dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;\n        }\n\n        mShaderMatrix.setScale(scale, scale);\n        mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top);\n\n        mBitmapShader.setLocalMatrix(mShaderMatrix);\n    }\n\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/view/widget/DividerItemDecoration.java",
    "content": "package me.shouheng.commons.view.widget;\n\nimport android.content.Context;\nimport android.content.res.TypedArray;\nimport android.graphics.Canvas;\nimport android.graphics.Rect;\nimport android.graphics.drawable.Drawable;\nimport androidx.core.content.ContextCompat;\nimport androidx.recyclerview.widget.LinearLayoutManager;\nimport androidx.recyclerview.widget.RecyclerView;\nimport android.view.View;\n\nimport me.shouheng.commons.R;\n\n\npublic class DividerItemDecoration extends RecyclerView.ItemDecoration {\n\n    public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;\n\n    public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;\n\n    private static final int[] ATTRS = new int[]{android.R.attr.listDivider};\n\n    private Drawable mDivider;\n\n    private int mOrientation;\n\n    public DividerItemDecoration(Context context, int orientation, boolean isDarkTheme) {\n        final TypedArray a = context.obtainStyledAttributes(ATTRS);\n        mDivider = ContextCompat.getDrawable(context, isDarkTheme ? R.drawable.item_divider_white : R.drawable.item_divider_black);\n        a.recycle();\n        setOrientation(orientation);\n    }\n\n    public DividerItemDecoration(Context context, int orientation, int resId) {\n        mDivider = ContextCompat.getDrawable(context, resId);\n        setOrientation(orientation);\n    }\n\n    public void setOrientation(int orientation) {\n        if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {\n            throw new IllegalArgumentException(\"invalid orientation\");\n        }\n        mOrientation = orientation;\n    }\n\n    @Override\n    public void onDraw(Canvas c, RecyclerView parent) {\n        if (mOrientation == VERTICAL_LIST) {\n            drawVertical(c, parent);\n        } else {\n            drawHorizontal(c, parent);\n        }\n    }\n\n    private void drawVertical(Canvas c, RecyclerView parent) {\n        final int left = parent.getPaddingLeft();\n        final int right = parent.getWidth() - parent.getPaddingRight();\n\n        final int childCount = parent.getChildCount();\n        for (int i = 0; i < childCount; i++) {\n            final View child = parent.getChildAt(i);\n            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();\n            final int top = child.getBottom() + params.bottomMargin;\n            final int bottom = top + mDivider.getIntrinsicHeight();\n            mDivider.setBounds(left, top, right, bottom);\n            mDivider.draw(c);\n        }\n    }\n\n    private void drawHorizontal(Canvas c, RecyclerView parent) {\n        final int top = parent.getPaddingTop();\n        final int bottom = parent.getHeight() - parent.getPaddingBottom();\n\n        final int childCount = parent.getChildCount();\n        for (int i = 0; i < childCount; i++) {\n            final View child = parent.getChildAt(i);\n            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();\n            final int left = child.getRight() + params.rightMargin;\n            final int right = left + mDivider.getIntrinsicHeight();\n\n            mDivider.setBounds(left, top, right, bottom);\n            mDivider.draw(c);\n        }\n    }\n\n    @Override\n    public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {\n        if (mOrientation == VERTICAL_LIST) {\n            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());\n        } else {\n            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);\n        }\n    }\n}"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/view/widget/DragSortRecycler.java",
    "content": "package me.shouheng.commons.view.widget;\n\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.graphics.Rect;\nimport android.graphics.drawable.BitmapDrawable;\nimport androidx.annotation.Nullable;\nimport androidx.recyclerview.widget.RecyclerView;\nimport android.util.Log;\nimport android.view.MotionEvent;\nimport android.view.View;\n\npublic class DragSortRecycler extends RecyclerView.ItemDecoration implements RecyclerView.OnItemTouchListener {\n\n    final String TAG = \"DragSortRecycler\";\n\n    final boolean DEBUG = false;\n    OnItemMovedListener moveInterface;\n    @Nullable\n    OnDragStateChangedListener dragStateChangedListener;\n    Paint bgColor = new Paint();\n    private int dragHandleWidth = 0;\n    private int selectedDragItemPos = -1;\n    private int fingerAnchorY;\n    RecyclerView.OnScrollListener scrollListener = new RecyclerView.OnScrollListener() {\n        @Override\n        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {\n            super.onScrollStateChanged(recyclerView, newState);\n        }\n\n        @Override\n        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {\n            super.onScrolled(recyclerView, dx, dy);\n            debugLog(\"Scrolled: \" + dx + \" \" + dy);\n            fingerAnchorY -= dy;\n        }\n    };\n    private int fingerY;\n    private int fingerOffsetInViewY;\n    private float autoScrollWindow = 0.1f;\n    private float autoScrollSpeed = 0.5f;\n    private BitmapDrawable floatingItem;\n    private Rect floatingItemStatingBounds;\n    private Rect floatingItemBounds;\n    private float floatingItemAlpha = 0.5f;\n    private int floatingItemBgColor = 0;\n    private int viewHandleId = -1;\n    private boolean isDragging;\n\n    private void debugLog(String log) {\n        if (DEBUG)\n            Log.d(TAG, log);\n    }\n\n    public RecyclerView.OnScrollListener getScrollListener() {\n        return scrollListener;\n    }\n\n    /*\n     * Set the item move interface\n     */\n    public void setOnItemMovedListener(OnItemMovedListener swif) {\n        moveInterface = swif;\n    }\n\n    public void setViewHandleId(int id) {\n        viewHandleId = id;\n    }\n\n    public void setLeftDragArea(int w) {\n        dragHandleWidth = w;\n    }\n\n    public void setFloatingAlpha(float a) {\n        floatingItemAlpha = a;\n    }\n\n    public void setFloatingBgColor(int c) {\n        floatingItemBgColor = c;\n    }\n\n    /*\n     Set the window at top and bottom of list, must be between 0 and 0.5\n     For example 0.1 uses the top and bottom 10% of the lists for scrolling\n     */\n    public void setAutoScrollWindow(float w) {\n        autoScrollWindow = w;\n    }\n\n    /*\n    Set the autoscroll speed, default is 0.5\n     */\n    public void setAutoScrollSpeed(float speed) {\n        autoScrollSpeed = speed;\n    }\n\n    @Override\n    public void getItemOffsets(Rect outRect, View view, RecyclerView rv, RecyclerView.State state) {\n        super.getItemOffsets(outRect, view, rv, state);\n\n        debugLog(\"getItemOffsets\");\n\n        debugLog(\"View top = \" + view.getTop());\n        if (selectedDragItemPos != -1) {\n            int itemPos = rv.getChildLayoutPosition(view);\n            debugLog(\"itemPos =\" + itemPos);\n\n            if (!canDragOver(itemPos)) {\n                return;\n            }\n\n            //Movement of finger\n            float totalMovement = fingerY - fingerAnchorY;\n\n            if (itemPos == selectedDragItemPos) {\n                view.setVisibility(View.INVISIBLE);\n            } else {\n                //Make view visible incase invisible\n                view.setVisibility(View.VISIBLE);\n\n                //Find middle of the floatingItem\n                float floatMiddleY = floatingItemBounds.top + floatingItemBounds.height() / 2;\n\n                //Moving down the list\n                //These will auto-animate if the device continually sends touch motion events\n                // if (totalMovment>0)\n                {\n                    if ((itemPos > selectedDragItemPos) && (view.getTop() < floatMiddleY)) {\n                        float amountUp = (floatMiddleY - view.getTop()) / (float) view.getHeight();\n                        //  amountUp *= 0.5f;\n                        if (amountUp > 1)\n                            amountUp = 1;\n\n                        outRect.top = -(int) (floatingItemBounds.height() * amountUp);\n                        outRect.bottom = (int) (floatingItemBounds.height() * amountUp);\n                    }\n\n                }//Moving up the list\n                // else if (totalMovment < 0)\n                {\n                    if ((itemPos < selectedDragItemPos) && (view.getBottom() > floatMiddleY)) {\n                        float amountDown = ((float) view.getBottom() - floatMiddleY) / (float) view.getHeight();\n                        //  amountDown *= 0.5f;\n                        if (amountDown > 1)\n                            amountDown = 1;\n\n                        outRect.top = (int) (floatingItemBounds.height() * amountDown);\n                        outRect.bottom = -(int) (floatingItemBounds.height() * amountDown);\n                    }\n                }\n            }\n        } else {\n            outRect.top = 0;\n            outRect.bottom = 0;\n            //Make view visible incase invisible\n            view.setVisibility(View.VISIBLE);\n        }\n    }\n\n    /**\n     * Find the new position by scanning through the items on\n     * screen and finding the positional relationship.\n     * This *seems* to work, another method would be to use\n     * getItemOffsets, but I think that could miss items?..\n     */\n    private int getNewPostion(RecyclerView rv) {\n        int itemsOnScreen = rv.getLayoutManager().getChildCount();\n\n        float floatMiddleY = floatingItemBounds.top + floatingItemBounds.height() / 2;\n\n        int above = 0;\n        int below = Integer.MAX_VALUE;\n        for (int n = 0; n < itemsOnScreen; n++) //Scan though items on screen, however they may not\n        {                                   // be in order!\n\n            View view = rv.getLayoutManager().getChildAt(n);\n\n            if (view.getVisibility() != View.VISIBLE)\n                continue;\n\n            int itemPos = rv.getChildLayoutPosition(view);\n\n            if (itemPos == selectedDragItemPos) //Don't check against itself!\n                continue;\n\n            float viewMiddleY = view.getTop() + view.getHeight() / 2;\n            if (floatMiddleY > viewMiddleY) //Is above this item\n            {\n                if (itemPos > above)\n                    above = itemPos;\n            } else if (floatMiddleY <= viewMiddleY) //Is below this item\n            {\n                if (itemPos < below)\n                    below = itemPos;\n            }\n        }\n        debugLog(\"above = \" + above + \" below = \" + below);\n\n        if (below != Integer.MAX_VALUE) {\n            if (below < selectedDragItemPos) //Need to count itself\n                below++;\n            return below - 1;\n        } else {\n            if (above < selectedDragItemPos)\n                above++;\n\n            return above;\n        }\n    }\n\n\n    @Override\n    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {\n        debugLog(\"onInterceptTouchEvent\");\n\n        //if (e.getAction() == MotionEvent.ACTION_DOWN)\n        {\n            View itemView = rv.findChildViewUnder(e.getX(), e.getY());\n\n            if (itemView == null)\n                return false;\n\n            boolean dragging = false;\n\n            if ((dragHandleWidth > 0) && (e.getX() < dragHandleWidth)) {\n                dragging = true;\n            } else if (viewHandleId != -1) {\n                //Find the handle in the list item\n                View handleView = itemView.findViewById(viewHandleId);\n\n                if (handleView == null) {\n                    Log.e(TAG, \"The view ID \" + viewHandleId + \" was not found in the RecycleView item\");\n                    return false;\n                }\n\n                //View should be visible to drag\n                if (handleView.getVisibility() != View.VISIBLE) {\n                    return false;\n                }\n\n                //We need to find the relative position of the handle to the parent view\n                //Then we can work out if the touch is within the handle\n                int[] parentItemPos = new int[2];\n                itemView.getLocationInWindow(parentItemPos);\n\n                int[] handlePos = new int[2];\n                handleView.getLocationInWindow(handlePos);\n\n                int xRel = handlePos[0] - parentItemPos[0];\n                int yRel = handlePos[1] - parentItemPos[1];\n\n                Rect touchBounds = new Rect(itemView.getLeft() + xRel, itemView.getTop() + yRel,\n                        itemView.getLeft() + xRel + handleView.getWidth(),\n                        itemView.getTop() + yRel + handleView.getHeight()\n                );\n\n                if (touchBounds.contains((int) e.getX(), (int) e.getY()))\n                    dragging = true;\n\n                debugLog(\"parentItemPos = \" + parentItemPos[0] + \" \" + parentItemPos[1]);\n                debugLog(\"handlePos = \" + handlePos[0] + \" \" + handlePos[1]);\n            }\n\n\n            if (dragging) {\n                debugLog(\"Started Drag\");\n\n                setIsDragging(true);\n\n                floatingItem = createFloatingBitmap(itemView);\n\n                fingerAnchorY = (int) e.getY();\n                fingerOffsetInViewY = fingerAnchorY - itemView.getTop();\n                fingerY = fingerAnchorY;\n\n                selectedDragItemPos = rv.getChildLayoutPosition(itemView);\n                debugLog(\"selectedDragItemPos = \" + selectedDragItemPos);\n\n                return true;\n            }\n        }\n        return false;\n    }\n\n    @Override\n    public void onRequestDisallowInterceptTouchEvent(boolean b) {\n\n    }\n\n    @Override\n    public void onTouchEvent(RecyclerView rv, MotionEvent e) {\n        debugLog(\"onTouchEvent\");\n\n        if ((e.getAction() == MotionEvent.ACTION_UP) ||\n                (e.getAction() == MotionEvent.ACTION_CANCEL)) {\n            if ((e.getAction() == MotionEvent.ACTION_UP) && selectedDragItemPos != -1) {\n                int newPos = getNewPostion(rv);\n                if (moveInterface != null)\n                    moveInterface.onItemMoved(selectedDragItemPos, newPos);\n            }\n\n            setIsDragging(false);\n            selectedDragItemPos = -1;\n            floatingItem = null;\n            rv.invalidateItemDecorations();\n            return;\n        }\n\n\n        fingerY = (int) e.getY();\n\n        if (floatingItem != null) {\n            floatingItemBounds.top = fingerY - fingerOffsetInViewY;\n\n            if (floatingItemBounds.top < -floatingItemStatingBounds.height() / 2) //Allow half the view out the top\n                floatingItemBounds.top = -floatingItemStatingBounds.height() / 2;\n\n            floatingItemBounds.bottom = floatingItemBounds.top + floatingItemStatingBounds.height();\n\n            floatingItem.setBounds(floatingItemBounds);\n        }\n\n        //Do auto scrolling at end of list\n        float scrollAmount = 0;\n        if (fingerY > (rv.getHeight() * (1 - autoScrollWindow))) {\n            scrollAmount = (fingerY - (rv.getHeight() * (1 - autoScrollWindow)));\n        } else if (fingerY < (rv.getHeight() * autoScrollWindow)) {\n            scrollAmount = (fingerY - (rv.getHeight() * autoScrollWindow));\n        }\n        debugLog(\"Scroll: \" + scrollAmount);\n\n        scrollAmount *= autoScrollSpeed;\n        rv.scrollBy(0, (int) scrollAmount);\n\n        rv.invalidateItemDecorations();// Redraw\n    }\n\n    private void setIsDragging(final boolean dragging) {\n        if (dragging != isDragging) {\n            isDragging = dragging;\n            if (dragStateChangedListener != null) {\n                if (isDragging) {\n                    dragStateChangedListener.onDragStart();\n                } else {\n                    dragStateChangedListener.onDragStop();\n                }\n            }\n        }\n    }\n\n    public void setOnDragStateChangedListener(final OnDragStateChangedListener dragStateChangedListener) {\n        this.dragStateChangedListener = dragStateChangedListener;\n    }\n\n    @Override\n    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {\n        if (floatingItem != null) {\n            floatingItem.setAlpha((int) (255 * floatingItemAlpha));\n            bgColor.setColor(floatingItemBgColor);\n            c.drawRect(floatingItemBounds, bgColor);\n            floatingItem.draw(c);\n        }\n    }\n\n    /**\n     * @param position\n     * @return True if we can drag the item over this position, False if not.\n     */\n    protected boolean canDragOver(int position) {\n        return true;\n    }\n\n    private BitmapDrawable createFloatingBitmap(View v) {\n        floatingItemStatingBounds = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());\n        floatingItemBounds = new Rect(floatingItemStatingBounds);\n\n        Bitmap bitmap = Bitmap.createBitmap(floatingItemStatingBounds.width(),\n                floatingItemStatingBounds.height(), Bitmap.Config.ARGB_8888);\n        Canvas canvas = new Canvas(bitmap);\n        v.draw(canvas);\n\n        BitmapDrawable retDrawable = new BitmapDrawable(v.getResources(), bitmap);\n        retDrawable.setBounds(floatingItemBounds);\n\n        return retDrawable;\n    }\n\n    public interface OnItemMovedListener {\n        void onItemMoved(int from, int to);\n    }\n\n\n    public interface OnDragStateChangedListener {\n        void onDragStart();\n\n        void onDragStop();\n    }\n}"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/view/widget/EmptyView.java",
    "content": "package me.shouheng.commons.view.widget;\n\nimport android.content.Context;\nimport android.content.res.TypedArray;\nimport androidx.databinding.DataBindingUtil;\nimport android.graphics.drawable.Drawable;\nimport androidx.annotation.DrawableRes;\nimport androidx.annotation.Nullable;\nimport android.text.TextUtils;\nimport android.util.AttributeSet;\nimport android.view.LayoutInflater;\nimport android.widget.LinearLayout;\n\nimport me.shouheng.commons.R;\nimport me.shouheng.commons.databinding.WidgetEmptyViewBinding;\nimport me.shouheng.commons.tools.ColorUtils;\nimport me.shouheng.commons.tools.PalmUtils;\n\n/**\n * Created by wangshouheng on 2017/8/9. */\npublic class EmptyView extends LinearLayout {\n\n    private boolean tintDrawable;\n\n    private WidgetEmptyViewBinding binding;\n\n    public EmptyView(Context context) {\n        this(context, null);\n    }\n\n    public EmptyView(Context context, @Nullable AttributeSet attrs) {\n        super(context, attrs);\n        init(context, attrs);\n    }\n\n    public EmptyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {\n        super(context, attrs, defStyleAttr);\n        init(context, attrs);\n    }\n\n    private void init(Context context, AttributeSet attributeSet) {\n        binding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.widget_empty_view, this, true);\n\n        TypedArray attr = context.obtainStyledAttributes(attributeSet, R.styleable.EmptyView, 0, 0);\n        int bottomTitleSize = attr.getDimensionPixelSize(R.styleable.EmptyView_title_size, 16);\n        int bottomSubTitleSize = attr.getDimensionPixelSize(R.styleable.EmptyView_sub_title_size, 14);\n        int mIcon = attr.getResourceId(R.styleable.EmptyView_empty_image, -1);\n        tintDrawable = attr.getBoolean(R.styleable.EmptyView_tint_drawable, false);\n        String bottomTitle = attr.getString(R.styleable.EmptyView_title);\n        String bottomSubTitle = attr.getString(R.styleable.EmptyView_sub_title);\n        attr.recycle();\n\n        binding.tvBottomTitle.setText(bottomTitle);\n        binding.tvBottomSubTitle.setText(bottomSubTitle);\n\n        binding.tvBottomTitle.setTextSize(bottomTitleSize);\n        binding.tvBottomSubTitle.setTextSize(bottomSubTitleSize);\n\n        binding.tvBottomTitle.setVisibility(TextUtils.isEmpty(bottomTitle) ? GONE : VISIBLE);\n        binding.tvBottomSubTitle.setVisibility(TextUtils.isEmpty(bottomSubTitle) ? GONE : VISIBLE);\n\n        if (mIcon != -1) binding.ivImage.setImageResource(mIcon);\n\n        if (tintDrawable) {\n            binding.ivImage.setImageDrawable(ColorUtils.tintDrawable(PalmUtils.getDrawableCompact(mIcon),\n                    PalmUtils.getColorCompact(R.color.light_theme_empty_icon_tint_color)));\n        }\n    }\n\n    public void setTitle(String title) {\n        binding.tvBottomTitle.setText(title);\n        binding.tvBottomTitle.setVisibility(TextUtils.isEmpty(title) ? GONE : VISIBLE);\n    }\n\n    public void setSubTitle(String subTitle) {\n        binding.tvBottomSubTitle.setText(subTitle);\n        binding.tvBottomSubTitle.setVisibility(TextUtils.isEmpty(subTitle) ? GONE : VISIBLE);\n    }\n\n    public void setIcon(@DrawableRes int mIcon) {\n        if (!tintDrawable) binding.ivImage.setImageResource(mIcon);\n        else {\n            binding.ivImage.setImageDrawable(ColorUtils.tintDrawable(PalmUtils.getDrawableCompact(mIcon),\n                    PalmUtils.getColorCompact(R.color.light_theme_empty_icon_tint_color)));\n        }\n    }\n\n    public void setIcon(Drawable drawable) {\n        binding.ivImage.setImageDrawable(tintDrawable ?\n                ColorUtils.tintDrawable(drawable, PalmUtils.getColorCompact(R.color.light_theme_empty_icon_tint_color)) : drawable);\n    }\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/view/widget/SpaceItemDecoration.java",
    "content": "package me.shouheng.commons.view.widget;\n\nimport android.graphics.Rect;\nimport androidx.recyclerview.widget.RecyclerView;\nimport android.view.View;\n\nimport me.shouheng.commons.tools.ViewUtils;\n\npublic class SpaceItemDecoration extends RecyclerView.ItemDecoration {\n\n    private int leftDp, upDp, rightDp, downDp;\n\n    public SpaceItemDecoration(int leftDp, int upDp, int rightDp, int downDp) {\n        this.leftDp = ViewUtils.dp2Px(leftDp);\n        this.upDp = ViewUtils.dp2Px(upDp);\n        this.rightDp = ViewUtils.dp2Px(rightDp);\n        this.downDp = ViewUtils.dp2Px(downDp);\n    }\n\n    @Override\n    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {\n        super.getItemOffsets(outRect, view, parent, state);\n        outRect.set(leftDp, upDp, rightDp, downDp);\n    }\n}"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/view/widget/SquareFrameLayout.java",
    "content": "package me.shouheng.commons.view.widget;\n\nimport android.content.Context;\nimport android.util.AttributeSet;\nimport android.widget.FrameLayout;\n\npublic class SquareFrameLayout extends FrameLayout {\n\n    public SquareFrameLayout(Context context, AttributeSet attrs, int defStyle) {\n        super(context, attrs, defStyle);\n    }\n\n    public SquareFrameLayout(Context context, AttributeSet attrs) {\n        super(context, attrs);\n    }\n\n    public SquareFrameLayout(Context context) {\n        super(context);\n    }\n\n    @SuppressWarnings(\"unused\")\n    @Override\n    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {\n        setMeasuredDimension(getDefaultSize(0, widthMeasureSpec), getDefaultSize(0, heightMeasureSpec));\n        int childWidthSize = getMeasuredWidth();\n        int childHeightSize = getMeasuredHeight();\n        heightMeasureSpec = widthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidthSize, MeasureSpec.EXACTLY);\n        super.onMeasure(widthMeasureSpec, heightMeasureSpec);\n    }\n}\n"
  },
  {
    "path": "commons/src/main/java/me/shouheng/commons/view/widget/SquareImageView.java",
    "content": "package me.shouheng.commons.view.widget;\n\nimport android.content.Context;\nimport androidx.appcompat.widget.AppCompatImageView;\nimport android.util.AttributeSet;\n\npublic class SquareImageView extends AppCompatImageView {\n\n    public SquareImageView(Context context) {\n        super(context);\n    }\n\n    public SquareImageView(Context context, AttributeSet attrs) {\n        super(context, attrs);\n    }\n\n    public SquareImageView(Context context, AttributeSet attrs, int defStyle) {\n        super(context, attrs, defStyle);\n    }\n\n    @Override\n    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {\n        super.onMeasure(widthMeasureSpec, heightMeasureSpec);\n        setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth());\n    }\n}"
  },
  {
    "path": "commons/src/main/res/drawable/bg_toolbar_shade.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"rectangle\">\n    <gradient\n        android:angle=\"-90\"\n        android:endColor=\"#00000000\"\n        android:startColor=\"#50000000\"/>\n</shape>\n"
  },
  {
    "path": "commons/src/main/res/drawable/ic_account_circle_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24.0\"\n        android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,5c1.66,0 3,1.34 3,3s-1.34,3 -3,3 -3,-1.34 -3,-3 1.34,-3 3,-3zM12,19.2c-2.5,0 -4.71,-1.28 -6,-3.22 0.03,-1.99 4,-3.08 6,-3.08 1.99,0 5.97,1.09 6,3.08 -1.29,1.94 -3.5,3.22 -6,3.22z\"/>\n</vector>\n"
  },
  {
    "path": "commons/src/main/res/drawable/ic_add_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24.0\"\n        android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\"/>\n</vector>\n"
  },
  {
    "path": "commons/src/main/res/drawable/ic_autorenew_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24.0\"\n        android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M12,6v3l4,-4 -4,-4v3c-4.42,0 -8,3.58 -8,8 0,1.57 0.46,3.03 1.24,4.26L6.7,14.8c-0.45,-0.83 -0.7,-1.79 -0.7,-2.8 0,-3.31 2.69,-6 6,-6zM18.76,7.74L17.3,9.2c0.44,0.84 0.7,1.79 0.7,2.8 0,3.31 -2.69,6 -6,6v-3l-4,4 4,4v-3c4.42,0 8,-3.58 8,-8 0,-1.57 -0.46,-3.03 -1.24,-4.26z\"/>\n</vector>\n"
  },
  {
    "path": "commons/src/main/res/drawable/ic_check_circle_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24.0\"\n        android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM10,17l-5,-5 1.41,-1.41L10,14.17l7.59,-7.59L19,8l-9,9z\"/>\n</vector>\n"
  },
  {
    "path": "commons/src/main/res/drawable/ic_close_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24.0\"\n        android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z\"/>\n</vector>\n"
  },
  {
    "path": "commons/src/main/res/drawable/ic_favorite_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24.0\"\n        android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M12,21.35l-1.45,-1.32C5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3c1.74,0 3.41,0.81 4.5,2.09C13.09,3.81 14.76,3 16.5,3 19.58,3 22,5.42 22,8.5c0,3.78 -3.4,6.86 -8.55,11.54L12,21.35z\"/>\n</vector>\n"
  },
  {
    "path": "commons/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillColor=\"#26A69A\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n"
  },
  {
    "path": "commons/src/main/res/drawable/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillType=\"evenOdd\"\n        android:pathData=\"M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"78.5885\"\n                android:endY=\"90.9159\"\n                android:startX=\"48.7653\"\n                android:startY=\"61.0927\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        android:pathData=\"M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\" />\n</vector>\n"
  },
  {
    "path": "commons/src/main/res/drawable/ic_widgets_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24.0\"\n        android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M13,13v8h8v-8h-8zM3,21h8v-8L3,13v8zM3,3v8h8L11,3L3,3zM16.66,1.69L11,7.34 16.66,13l5.66,-5.66 -5.66,-5.65z\"/>\n</vector>\n"
  },
  {
    "path": "commons/src/main/res/drawable/item_divider_black.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"rectangle\">\n    <size android:height=\"1px\" />\n    <solid android:color=\"#15000000\" />\n</shape>"
  },
  {
    "path": "commons/src/main/res/drawable/item_divider_white.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"rectangle\">\n    <size android:height=\"1px\" />\n    <solid android:color=\"#15ffffff\" />\n</shape>"
  },
  {
    "path": "commons/src/main/res/drawable/nav_item_color.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item android:state_checked=\"true\"\n        android:color=\"@color/colorNavItemSelected\" />\n    <item android:color=\"@color/colorNavItemUnselected\"  />\n</selector>"
  },
  {
    "path": "commons/src/main/res/layout/layout_toolbar.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <LinearLayout\n        android:orientation=\"vertical\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\">\n\n        <com.google.android.material.appbar.AppBarLayout\n            android:id=\"@+id/bar_layout\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\">\n\n            <androidx.appcompat.widget.Toolbar\n                android:id=\"@+id/toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?attr/actionBarSize\"/>\n\n        </com.google.android.material.appbar.AppBarLayout>\n\n    </LinearLayout>\n\n</layout>"
  },
  {
    "path": "commons/src/main/res/layout/widget_empty_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\">\n\n    <LinearLayout\n        android:orientation=\"vertical\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\">\n\n        <androidx.appcompat.widget.AppCompatImageView\n            android:id=\"@+id/iv_image\"\n            android:layout_gravity=\"center_horizontal\"\n            android:layout_width=\"@dimen/empty_view_size\"\n            android:layout_height=\"@dimen/empty_view_size\" />\n\n        <TextView\n            android:id=\"@+id/tv_bottom_title\"\n            tools:text=\"This is the title of this illustration.\"\n            android:layout_marginTop=\"20dp\"\n            android:layout_marginStart=\"64dp\"\n            android:layout_marginEnd=\"64dp\"\n            android:textSize=\"16sp\"\n            android:textColor=\"@color/black54\"\n            android:layout_gravity=\"center_horizontal\"\n            android:gravity=\"center_horizontal\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\" />\n\n        <TextView\n            android:id=\"@+id/tv_bottom_sub_title\"\n            tools:text=\"This is the demo text of the sub title of this empty image view.\"\n            android:textSize=\"14sp\"\n            android:textColor=\"@color/black38\"\n            android:layout_marginStart=\"20dp\"\n            android:layout_marginEnd=\"20dp\"\n            android:layout_gravity=\"center_horizontal\"\n            android:gravity=\"center_horizontal\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\" />\n\n    </LinearLayout>\n\n</layout>"
  },
  {
    "path": "commons/src/main/res/values/attrs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <declare-styleable name=\"CircleImageView\">\n        <attr name=\"border_width\" format=\"dimension\" />\n        <attr name=\"border_color\" format=\"color\" />\n        <attr name=\"border_overlay\" format=\"boolean\" />\n    </declare-styleable>\n\n    <declare-styleable name=\"EmptyView\">\n        <attr name=\"title\" format=\"string\"/>\n        <attr name=\"title_size\" format=\"dimension|reference\"/>\n        <attr name=\"sub_title\" format=\"string\"/>\n        <attr name=\"sub_title_size\" format=\"dimension|reference\"/>\n        <attr name=\"empty_image\" format=\"reference\"/>\n        <attr name=\"tint_drawable\" format=\"boolean\" />\n    </declare-styleable>\n</resources>"
  },
  {
    "path": "commons/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#FAFAFA</color>\n    <color name=\"colorPrimaryDark\">#FAFAFA</color>\n    <color name=\"colorAccent\">#0078FF</color>\n\n    <color name=\"dark_theme_background\">#2E2E2E</color>\n    <color name=\"dark_theme_foreground\">#3F3F3F</color>\n\n    <color name=\"light_theme_background\">#FAFAFA</color>\n\n    <color name=\"black20\">#33000000</color>\n    <color name=\"black38\">#61000000</color>\n    <color name=\"black54\">#8A000000</color>\n    <color name=\"black87\">#D8000000</color>\n\n    <color name=\"white20\">#33ffffff</color>\n    <color name=\"white38\">#61ffffff</color>\n    <color name=\"white54\">#8Affffff</color>\n    <color name=\"white87\">#D8ffffff</color>\n\n    <color name=\"light_theme_empty_text_color\">@color/black54</color>\n    <color name=\"light_theme_empty_sub_text_color\">@color/black38</color>\n    <color name=\"light_theme_empty_icon_tint_color\">@color/black38</color>\n    <color name=\"dark_theme_empty_text_color\">@color/white54</color>\n    <color name=\"dark_theme_empty_sub_text_color\">@color/white38</color>\n    <color name=\"dark_theme_empty_icon_tint_color\">@color/white38</color>\n\n    <color name=\"intro_color_1\">#222222</color>\n    <color name=\"intro_color_2\">#c52829</color>\n    <color name=\"intro_color_3\">#f77910</color>\n    <color name=\"intro_color_4\">#21dba4</color>\n    <color name=\"intro_color_5\">#9C27B0</color>\n\n    <color name=\"colorNavItemUnselected\">#757575</color>\n    <color name=\"colorNavItemSelected\">@color/colorAccent</color>\n\n</resources>\n"
  },
  {
    "path": "commons/src/main/res/values/dimens.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <dimen name=\"empty_view_size\">120dp</dimen>\n\n    <dimen name=\"fab_margin\">16dp</dimen>\n</resources>"
  },
  {
    "path": "commons/src/main/res/values/strings.xml",
    "content": "<resources>\n\n    <string name=\"app_name\">安卓开发参考</string>\n\n    <string name=\"menu_item_title_0\">主界面</string>\n    <string name=\"menu_item_desc_0\">应用简介</string>\n    <string name=\"menu_item_title_1\">视频直播</string>\n    <string name=\"menu_item_desc_1\">使用《全民直播》的API</string>\n    <string name=\"menu_item_title_2\">果壳新闻</string>\n    <string name=\"menu_item_desc_2\">使用果壳网的API</string>\n    <string name=\"menu_item_title_3\">布局</string>\n    <string name=\"menu_item_desc_3\">经典的Material布局</string>\n    <string name=\"menu_item_title_4\">框架</string>\n    <string name=\"menu_item_desc_4\">常用的第三方框架</string>\n    <string name=\"menu_item_title_5\">开眼视频</string>\n    <string name=\"menu_item_desc_5\">开眼视频的API</string>\n    <string name=\"menu_item_title_6\">动画|效果</string>\n    <string name=\"menu_item_desc_6\">动画和效果合集</string>\n    <string name=\"menu_item_title_7\">高级</string>\n    <string name=\"menu_item_desc_7\">AIDL测试程序</string>\n    <string name=\"menu_item_sub_title_1\">Navigation</string>\n    <string name=\"menu_item_sub_desc_1\">Navigation经典布局</string>\n    <string name=\"menu_item_sub_title_2\">Tabbed</string>\n    <string name=\"menu_item_sub_desc_2\">Tabbed经典布局</string>\n    <string name=\"menu_item_sub_title_3\">Bottom sheet</string>\n    <string name=\"menu_item_sub_desc_3\">Bottom sheet 经典布局</string>\n    <string name=\"menu_item_sub_title_4\">Scrolling</string>\n    <string name=\"menu_item_sub_desc_4\">Scrolling 经典布局</string>\n    <string name=\"menu_item_sub_title_5\">Collapse</string>\n    <string name=\"menu_item_sub_desc_5\">Collapse 经典布局</string>\n    <string name=\"add_account\">添加账号</string>\n    <string name=\"manage_account\">管理账号</string>\n\n    <string name=\"developer_name\">WngShhng</string>\n    <string name=\"developer_email\">shouheng2015@gmail.com</string>\n\n    <string name=\"live_title\">视频直播</string>\n    <string name=\"live_sub_title\">使用《全民直播》的API</string>\n    <string name=\"live_recommend_more\">更多</string>\n    <string name=\"live_living\">直播</string>\n    <string name=\"live_views_number\">%d 观看</string>\n    <string name=\"live_follows_number\">%d 人关注</string>\n    <string name=\"live_subscribe\">关注</string>\n    <string name=\"live_qm_account\">全民号: %s</string>\n\n    <string name=\"nav_bottom_item_1\">主界面</string>\n    <string name=\"nav_bottom_item_2\">收藏</string>\n    <string name=\"nav_bottom_desc_2\">这里是Navigation布局页面中的收藏页面的实例</string>\n    <string name=\"nav_bottom_item_3\">我</string>\n    <string name=\"nav_bottom_desc_3\">这里是Navigation布局页面中的个人信息页面的实例</string>\n\n    <string name=\"what_for\">项目简介</string>\n    <string name=\"what_for_detail\">该项目用作Android高级开发的演示</string>\n\n    <string name=\"bottom_sheet_default_content\">Bottom Sheet的内部布局</string>\n\n    <string name=\"lan_ting_xu\">\\t永和九年，岁在癸（guǐ）丑，暮春之初，会于会稽（kuài jī）山阴之兰亭，修禊（xì）事也。\n        群贤毕至，少长咸集。此地有崇山峻岭，茂林修竹， 又有清流激湍（tuān），映带左右。\n        引以为流觞（shāng）曲（ qū）水，列坐其次，虽无丝竹管弦之盛，一觞（shang)一咏，亦足以畅叙幽情。\\n\\n\n        \\t是日也，天朗气清，惠风和畅。仰观宇宙之大，俯察品类之盛，所以游目骋（chěng）怀，足以极视听之娱，信可乐也。\\n\\n\n        夫人之相与，俯仰一世。或取诸怀抱，悟言一室之内；或因寄所托，放浪形骸（hái）之外。\n        虽趣（qǔ）舍万殊，静躁不同，当其欣于所遇，暂得于己，怏（同“快”）然自足，不知老之将至。\n        及其所之既倦，情随事迁，感慨系（xì）之矣。向之所欣，俯仰之间，已为陈迹，犹不能不以之兴怀。\n        况修短随化，终期于尽。古人云：“死生亦大矣。”岂不痛哉！\\n\\n\n        \\t每览昔人兴感之由，若合一契，未尝不临文嗟（jiē）悼，不能喻之于怀。固知一死生为虚诞，齐彭殇(shāng)为妄作。\n        后之视今，亦犹今之视昔，悲夫！故列叙时人，录其所述。虽世殊事异，所以兴怀，其致一也。后之览者，亦将有感于斯文。</string>\n\n    <string name=\"failed_to_create_file\">Failed to create file</string>\n    <string name=\"storage_not_available\">Storage unavailable</string>\n\n    <string name=\"permission_setting_permission\">Permission settings</string>\n    <string name=\"permission_storage_permission\">Storage</string>\n    <string name=\"permission_location_permission\">Location</string>\n    <string name=\"permission_microphone_permission\">Microphone</string>\n    <string name=\"permission_phone_permission\">Phone</string>\n    <string name=\"permission_sms_permission\">Sms</string>\n    <string name=\"permission_sensor_permission\">Sensor</string>\n    <string name=\"permission_contacts_permission\">Contacts</string>\n    <string name=\"permission_camera_permission\">Camera</string>\n    <string name=\"permission_calendar_permission\">Calendar</string>\n    <string name=\"permission_default_permission_name\">permission</string>\n    <string name=\"setting_permission\">Setting permission</string>\n    <string name=\"set_permission_in_setting\">Permission is required.\\n\\nGrant the permission to this application and try again:\\n\\n Open app info page in settings, tap \\\"Permissions\\\", enable \\\"%s\\\".</string>\n    <string name=\"permission_denied_try_again_after_set\">Permission denied. Please try again after grant the permission.</string>\n    <string name=\"permission_denied_try_again_after_set_given_permission\">Permission denied. Please try again after grant the %s permission.</string>\n\n    <string name=\"to_set\">to set</string>\n    <string name=\"cancel\">Cancel</string>\n\n    <!--region libraries-->\n    <string name=\"library_menu_event_bus\">EventBus</string>\n    <string name=\"library_menu_rxjava\">RxJava</string>\n    <string name=\"library_menu_clip\">图片裁剪</string>\n    <string name=\"library_menu_timber\">Timber</string>\n    <string name=\"library_menu_my_knife\">MyKnife</string>\n    <string name=\"libraries_finger\">指纹识别</string>\n    <string name=\"libraries_workmanager\">WorkManager</string>\n    <string name=\"libraries_serialize\">序列化</string>\n    <string name=\"libraries_handler\">Handler</string>\n    <string name=\"libraries_timezone\">时区</string>\n    <string name=\"libraries_compress\">图片压缩</string>\n\n    <string name=\"library_navigation_to_2\">Navigation to activity 2</string>\n    <string name=\"library_register_event_bus\">Register event bus</string>\n    <string name=\"library_register_sticky_event\">Register sticky event</string>\n\n    <string name=\"text_send\">Send</string>\n    <string name=\"text_publish\">Publish</string>\n    <string name=\"text_publish_and_finish\">Publish &amp; finish</string>\n    <string name=\"text_publish_sticky_event\">Publish sticky event</string>\n    <string name=\"event_bus_stop_delivery\">Stop delivery</string>\n\n    <string name=\"libraries_compress_compress\">邻近采样压缩</string>\n    <string name=\"libraries_compress_scale\">双线性采样</string>\n    <string name=\"libraries_compress_compress_original\">原始图片尺寸：宽度 %d, 高度 %d</string>\n    <string name=\"libraries_compress_compress_result\">压缩图片尺寸：宽度 %d, 高度 %d</string>\n    <!--endregion-->\n\n</resources>\n"
  },
  {
    "path": "commons/src/main/res/values/styles.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <style name=\"AppTheme.AppBarOverlay\" parent=\"@style/ThemeOverlay.AppCompat.Dark\" />\n    <style name=\"AppTheme.PopupOverlay\" parent=\"ThemeOverlay.AppCompat.Light\" />\n</resources>"
  },
  {
    "path": "commons/src/main/res/xml/network_security_config.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<network-security-config>\n    <domain-config cleartextTrafficPermitted=\"true\">\n        <domain includeSubdomains=\"true\">kaiyanapp.com</domain>\n        <domain includeSubdomains=\"true\">guokr.com</domain>\n        <domain includeSubdomains=\"true\">quanmin.tv</domain>\n        <domain includeSubdomains=\"true\">amdcopen.m.taobao.com</domain>\n    </domain-config>\n</network-security-config>"
  },
  {
    "path": "commons/src/test/java/me/shouheng/commons/ExampleUnitTest.java",
    "content": "package me.shouheng.commons;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "eyepetizer/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "eyepetizer/build.gradle",
    "content": "println isEyepetizerModuleApp.toBoolean()\n\nif (isEyepetizerModuleApp.toBoolean()) {\n    apply plugin: 'com.android.application'\n} else {\n    apply plugin: 'com.android.library'\n}\n\nandroid {\n    compileSdkVersion rootProject.ext.compileSdkVersion\n    defaultConfig {\n        minSdkVersion rootProject.ext.minSdkVersion\n        targetSdkVersion rootProject.ext.targetSdkVersion\n        versionCode 1\n        versionName \"1.0\"\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n        javaCompileOptions {\n            annotationProcessorOptions {\n                arguments = [moduleName: project.getName()]\n            }\n        }\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n    // use data binding\n    dataBinding {\n        enabled = true\n    }\n    // use java 8 language\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n    // use external libs folder\n    sourceSets {\n        main {\n            jniLibs.srcDirs = ['libs']\n            if (isEyepetizerModuleApp.toBoolean()) {\n                manifest.srcFile \"src/main/debug/AndroidManifest.xml\"\n            } else {\n                manifest.srcFile \"src/main/AndroidManifest.xml\"\n            }\n        }\n    }\n}\n\ndependencies {\n    implementation fileTree(dir: 'libs', include: ['*.jar'])\n    testImplementation 'junit:junit:4.12'\n    androidTestImplementation 'androidx.test:runner:1.1.0'\n    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'\n    // router\n    annotationProcessor 'com.alibaba:arouter-compiler:1.1.4'\n    // projects\n    implementation project(':commons')\n}\n"
  },
  {
    "path": "eyepetizer/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "eyepetizer/src/androidTest/java/me/shouheng/eyepetizer/ExampleInstrumentedTest.java",
    "content": "package me.shouheng.eyepetizer;\n\nimport android.content.Context;\nimport androidx.test.InstrumentationRegistry;\nimport androidx.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"me.shouheng.eyepetizer\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "eyepetizer/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"me.shouheng.eyepetizer\">\n\n    <application\n        android:networkSecurityConfig=\"@xml/network_security_config\"\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <activity android:name=\".ui.activity.HomeActivity\" />\n        <activity android:name=\".ui.activity.ContainerActivity\"/>\n    </application>\n\n</manifest>"
  },
  {
    "path": "eyepetizer/src/main/debug/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"me.shouheng.eyepetizer\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />\n    <uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\" />\n    <uses-permission android:name=\"android.permission.READ_PHONE_STATE\" />\n    <uses-permission android:name=\"android.permission.WAKE_LOCK\" />\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\"\n        android:name=\".ModuleEyepetizerApp\" >\n\n        <activity android:name=\".ui.activity.HomeActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "eyepetizer/src/main/java/me/shouheng/eyepetizer/ModuleEyepetizerApp.java",
    "content": "package me.shouheng.eyepetizer;\n\nimport com.alibaba.android.arouter.launcher.ARouter;\n\nimport me.shouheng.commons.BaseApplication;\n\n/**\n * @author shouh\n * @version $Id: ModuleGuokrApp, v 0.1 2018/6/6 22:30 shouh Exp$\n */\npublic class ModuleEyepetizerApp extends BaseApplication {\n\n    private static ModuleEyepetizerApp application;\n\n    public static ModuleEyepetizerApp getContext() {\n        return application;\n    }\n\n    @Override\n    public void onCreate() {\n        super.onCreate();\n        application = this;\n\n        ARouter.init(this);\n    }\n}\n"
  },
  {
    "path": "eyepetizer/src/main/java/me/shouheng/eyepetizer/mvp/base/BasePresenter.java",
    "content": "package me.shouheng.eyepetizer.mvp.base;\n\n/**\n * @author shouh\n * @version $Id: BasePresenter, v 0.1 2018/8/19 17:14 shouh Exp$\n */\npublic interface BasePresenter {\n}\n"
  },
  {
    "path": "eyepetizer/src/main/java/me/shouheng/eyepetizer/mvp/base/BaseView.java",
    "content": "package me.shouheng.eyepetizer.mvp.base;\n\n/**\n * @author shouh\n * @version $Id: BaseView, v 0.1 2018/8/19 17:13 shouh Exp$\n */\npublic interface BaseView {\n}\n"
  },
  {
    "path": "eyepetizer/src/main/java/me/shouheng/eyepetizer/mvp/contract/HomeContract.java",
    "content": "package me.shouheng.eyepetizer.mvp.contract;\n\nimport java.util.List;\n\nimport me.shouheng.eyepetizer.mvp.base.BasePresenter;\nimport me.shouheng.eyepetizer.mvp.base.BaseView;\nimport me.shouheng.eyepetizer.mvp.model.bean.HomeBean;\n\n/**\n * @author shouh\n * @version $Id: HomeContract, v 0.1 2018/8/19 17:10 shouh Exp$\n */\npublic interface HomeContract {\n\n    interface IView extends BaseView {\n        void setFirstPage(List<HomeBean.IssueList.ItemList> itemLists);\n        void setNextPage(List<HomeBean.IssueList.ItemList> itemLists);\n        void onError(String msg);\n    }\n\n    interface IPresenter extends BasePresenter {\n        void requestFirstPage();\n        void requestNextPage();\n    }\n}\n"
  },
  {
    "path": "eyepetizer/src/main/java/me/shouheng/eyepetizer/mvp/model/HomeModel.java",
    "content": "package me.shouheng.eyepetizer.mvp.model;\n\nimport io.reactivex.Observable;\nimport me.shouheng.eyepetizer.mvp.model.bean.HomeBean;\nimport me.shouheng.eyepetizer.net.APIRetrofit;\n\n/**\n * @author shouh\n * @version $Id: HomeModel, v 0.1 2018/8/19 17:27 shouh Exp$\n */\npublic class HomeModel {\n\n    public Observable<HomeBean> getFirstHomeData() {\n        return APIRetrofit.getEyepetizerService().getFirstHomeData(System.currentTimeMillis());\n    }\n\n    public Observable<HomeBean> getMoreHomeData(String url) {\n        return APIRetrofit.getEyepetizerService().getMoreHomeData(url);\n    }\n}\n"
  },
  {
    "path": "eyepetizer/src/main/java/me/shouheng/eyepetizer/mvp/model/bean/HomeBean.java",
    "content": "package me.shouheng.eyepetizer.mvp.model.bean;\n\nimport java.util.List;\n\n/**\n * @author shouh\n * @version $Id: HomeBean, v 0.1 2018/8/19 17:19 shouh Exp$\n */\npublic class HomeBean {\n\n    /**\n     * issueList : [{\"releaseTime\":1534640400000,\"type\":\"morning\",\"date\":1534640400000,\"publishTime\":1534640400000,\"itemList\":[{\"type\":\"video\",\"data\":{\"dataType\":\"VideoBeanForClient\",\"id\":122208,\"title\":\"致敬经典：当吉卜力动画走进现实\",\"description\":\"本片作者是来自韩国的 Kojer，他将吉卜力工作室耳熟能详的动画人物「放」进了真实的世界中，竟毫无违和感。有「千与千寻」、「龙猫」和「天空之城」等，你最爱的是哪一个场景？From Sunflower12\",\"library\":\"DAILY\",\"tags\":[{\"id\":470,\"name\":\"吉卜力\",\"actionUrl\":\"eyepetizer://tag/470/?title=%E5%90%89%E5%8D%9C%E5%8A%9B\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/2d50274d224680bf06d3062d6874482b.jpeg?imageMogr2/quality/60\",\"headerImage\":\"http://img.kaiyanapp.com/2d50274d224680bf06d3062d6874482b.jpeg?imageMogr2/quality/60\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":570,\"name\":\"电影相关\",\"actionUrl\":\"eyepetizer://tag/570/?title=%E7%94%B5%E5%BD%B1%E7%9B%B8%E5%85%B3\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/bee7c0cd647345f911c10be60ffcde93.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/bee7c0cd647345f911c10be60ffcde93.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":506,\"name\":\"经典\",\"actionUrl\":\"eyepetizer://tag/506/?title=%E7%BB%8F%E5%85%B8\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/1e948eab70737d8beca9f52fce907ab5.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/1e948eab70737d8beca9f52fce907ab5.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":424,\"name\":\"宫崎骏\",\"actionUrl\":\"eyepetizer://tag/424/?title=%E5%AE%AB%E5%B4%8E%E9%AA%8F\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/00f9596704c7eeb7ef65d095b453c8b3.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/00f9596704c7eeb7ef65d095b453c8b3.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":749,\"name\":\"影视周边\",\"actionUrl\":\"eyepetizer://tag/749/?title=%E5%BD%B1%E8%A7%86%E5%91%A8%E8%BE%B9\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/787bc5416e2a985520834eafa9d132af.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/787bc5416e2a985520834eafa9d132af.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null}],\"consumption\":{\"collectionCount\":1000,\"shareCount\":641,\"replyCount\":33},\"resourceType\":\"video\",\"slogan\":\"世界瞬间变成令人感动的童话乐园\",\"provider\":{\"name\":\"YouTube\",\"alias\":\"youtube\",\"icon\":\"http://img.kaiyanapp.com/fa20228bc5b921e837156923a58713f6.png\"},\"category\":\"影视\",\"author\":{\"id\":2173,\"icon\":\"http://img.kaiyanapp.com/003829087e85ce7310b2210d9575ce67.jpeg\",\"name\":\"开眼影视精选\",\"description\":\"关于电影、剧集的一切\",\"link\":\"\",\"latestReleaseTime\":1534640409000,\"videoNum\":442,\"adTrack\":null,\"follow\":{\"itemType\":\"author\",\"itemId\":2173,\"followed\":false},\"shield\":{\"itemType\":\"author\",\"itemId\":2173,\"shielded\":false},\"approvedNotReadyVideoCount\":0,\"ifPgc\":true},\"cover\":{\"feed\":\"http://img.kaiyanapp.com/11f42b2135bb7553b144f5fc7111a56f.jpeg?imageMogr2/quality/60/format/jpg\",\"detail\":\"http://img.kaiyanapp.com/11f42b2135bb7553b144f5fc7111a56f.jpeg?imageMogr2/quality/60/format/jpg\",\"blurred\":\"http://img.kaiyanapp.com/a7399848cb61d7ea2e7707050cc7b243.jpeg?imageMogr2/quality/60/format/jpg\",\"sharing\":null,\"homepage\":\"http://img.kaiyanapp.com/11f42b2135bb7553b144f5fc7111a56f.jpeg?imageView2/1/w/720/h/560/format/jpg/q/75|watermark/1/image/aHR0cDovL2ltZy5rYWl5YW5hcHAuY29tL2JsYWNrXzMwLnBuZw==/dissolve/100/gravity/Center/dx/0/dy/0|imageslim\"},\"playUrl\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=default&source=aliyun\",\"thumbPlayUrl\":null,\"duration\":220,\"webUrl\":{\"raw\":\"http://www.eyepetizer.net/detail.html?vid=122208\",\"forWeibo\":\"http://www.eyepetizer.net/detail.html?vid=122208&resourceType=video&utm_campaign=routine&utm_medium=share&utm_source=weibo&uid=0\"},\"releaseTime\":1534640409000,\"playInfo\":[{\"height\":480,\"width\":854,\"urlList\":[{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=normal&source=aliyun\",\"size\":25152959},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=normal&source=qcloud\",\"size\":25152959},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=normal&source=ucloud\",\"size\":25152959}],\"name\":\"标清\",\"type\":\"normal\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=normal&source=aliyun\"},{\"height\":720,\"width\":1280,\"urlList\":[{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=high&source=aliyun\",\"size\":36837465},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=high&source=qcloud\",\"size\":36837465},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=high&source=ucloud\",\"size\":36837465}],\"name\":\"高清\",\"type\":\"high\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=high&source=aliyun\"}],\"campaign\":null,\"waterMarks\":null,\"adTrack\":null,\"type\":\"NORMAL\",\"titlePgc\":null,\"descriptionPgc\":null,\"remark\":null,\"ifLimitVideo\":false,\"searchWeight\":0,\"idx\":0,\"shareAdTrack\":null,\"favoriteAdTrack\":null,\"webAdTrack\":null,\"date\":1534640400000,\"promotion\":null,\"label\":null,\"labelList\":[],\"descriptionEditor\":\"本片作者是来自韩国的 Kojer，他将吉卜力工作室耳熟能详的动画人物「放」进了真实的世界中，竟毫无违和感。有「千与千寻」、「龙猫」和「天空之城」等，你最爱的是哪一个场景？From Sunflower12\",\"collected\":false,\"played\":false,\"subtitles\":[],\"lastViewTime\":null,\"playlists\":null,\"src\":null},\"tag\":null,\"id\":0,\"adIndex\":-1},{\"type\":\"video\",\"data\":{\"dataType\":\"VideoBeanForClient\",\"id\":121783,\"title\":\"韩国反套路广告：高中生的爱情\",\"description\":\"穿着校服的男孩和女孩，怎么看起来像在拍韩剧？这么想你就错了，这只是广告。男孩打篮球时穿的衣服上没有汗，被女孩认为骗了她，看到最后才发现是\\u2026\\u2026虽然男女主演技有点尴尬，但这个脑洞你不得不服啊。From 티몬 TMON Official\",\"library\":\"DAILY\",\"tags\":[{\"id\":748,\"name\":\"广告精选\",\"actionUrl\":\"eyepetizer://tag/748/?title=%E5%B9%BF%E5%91%8A%E7%B2%BE%E9%80%89\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/431177a6b2177788aa4d8eff8073d9a7.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/431177a6b2177788aa4d8eff8073d9a7.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"IMPORTANT\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":504,\"name\":\"笑cry\",\"actionUrl\":\"eyepetizer://tag/504/?title=%E7%AC%91cry\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/3d3cb19d13cc16e8c3c2eddb12284fa3.jpeg?imageMogr2/quality/100\",\"headerImage\":\"http://img.kaiyanapp.com/177986653f12273f6d55edafe856ffe3.jpeg?imageMogr2/quality/100\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":150,\"name\":\"青春\",\"actionUrl\":\"eyepetizer://tag/150/?title=%E9%9D%92%E6%98%A5\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/34d33f611dbfe38e4d00cd4ab43212e7.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/58e3e0ec1e583a6debcc0f80d16c86fe.jpeg?imageMogr2/quality/100\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":108,\"name\":\"爱情\",\"actionUrl\":\"eyepetizer://tag/108/?title=%E7%88%B1%E6%83%85\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/67025fb5bf4f8ff4ccd63cdcfd0cd6c6.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/67025fb5bf4f8ff4ccd63cdcfd0cd6c6.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":16,\"name\":\"广告\",\"actionUrl\":\"eyepetizer://tag/16/?title=%E5%B9%BF%E5%91%8A\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/e41e74fe73882b552de00d95d56748d2.jpeg?imageMogr2/quality/60\",\"headerImage\":\"http://img.kaiyanapp.com/3054658dbd559ac42c4c282e9cab7a32.jpeg?imageMogr2/quality/100\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null}],\"consumption\":{\"collectionCount\":128,\"shareCount\":103,\"replyCount\":20},\"resourceType\":\"video\",\"slogan\":\"偶像剧包装下的清奇脑回路\",\"provider\":{\"name\":\"YouTube\",\"alias\":\"youtube\",\"icon\":\"http://img.kaiyanapp.com/fa20228bc5b921e837156923a58713f6.png\"},\"category\":\"广告\",\"author\":{\"id\":2162,\"icon\":\"http://img.kaiyanapp.com/98beab66d3885a139b54f21e91817c4f.jpeg\",\"name\":\"开眼广告精选\",\"description\":\"为广告人的精彩创意点赞\",\"link\":\"\",\"latestReleaseTime\":1534640412000,\"videoNum\":1000,\"adTrack\":null,\"follow\":{\"itemType\":\"author\",\"itemId\":2162,\"followed\":false},\"shield\":{\"itemType\":\"author\",\"itemId\":2162,\"shielded\":false},\"approvedNotReadyVideoCount\":0,\"ifPgc\":true},\"cover\":{\"feed\":\"http://img.kaiyanapp.com/699d698e9c6a210453bf6785dc75d80a.png?imageMogr2/quality/60/format/jpg\",\"detail\":\"http://img.kaiyanapp.com/699d698e9c6a210453bf6785dc75d80a.png?imageMogr2/quality/60/format/jpg\",\"blurred\":\"http://img.kaiyanapp.com/247f776b9d2ac64e489ac676c67600cb.png?imageMogr2/quality/60/format/jpg\",\"sharing\":null,\"homepage\":\"http://img.kaiyanapp.com/699d698e9c6a210453bf6785dc75d80a.png?imageView2/1/w/720/h/560/format/jpg/q/75|watermark/1/image/aHR0cDovL2ltZy5rYWl5YW5hcHAuY29tL2JsYWNrXzMwLnBuZw==/dissolve/100/gravity/Center/dx/0/dy/0|imageslim\"},\"playUrl\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121783&resourceType=video&editionType=default&source=aliyun\",\"thumbPlayUrl\":null,\"duration\":206,\"webUrl\":{\"raw\":\"http://www.eyepetizer.net/detail.html?vid=121783\",\"forWeibo\":\"http://www.eyepetizer.net/detail.html?vid=121783&resourceType=video&utm_campaign=routine&utm_medium=share&utm_source=weibo&uid=0\"},\"releaseTime\":1534640412000,\"playInfo\":[{\"height\":480,\"width\":854,\"urlList\":[{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121783&resourceType=video&editionType=normal&source=aliyun\",\"size\":10596486},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121783&resourceType=video&editionType=normal&source=qcloud\",\"size\":10596486},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121783&resourceType=video&editionType=normal&source=ucloud\",\"size\":10596486}],\"name\":\"标清\",\"type\":\"normal\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121783&resourceType=video&editionType=normal&source=aliyun\"},{\"height\":720,\"width\":1280,\"urlList\":[{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121783&resourceType=video&editionType=high&source=aliyun\",\"size\":21560023},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121783&resourceType=video&editionType=high&source=qcloud\",\"size\":21560023},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121783&resourceType=video&editionType=high&source=ucloud\",\"size\":21560023}],\"name\":\"高清\",\"type\":\"high\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121783&resourceType=video&editionType=high&source=aliyun\"}],\"campaign\":null,\"waterMarks\":null,\"adTrack\":null,\"type\":\"NORMAL\",\"titlePgc\":null,\"descriptionPgc\":null,\"remark\":null,\"ifLimitVideo\":false,\"searchWeight\":0,\"idx\":0,\"shareAdTrack\":null,\"favoriteAdTrack\":null,\"webAdTrack\":null,\"date\":1534640400000,\"promotion\":null,\"label\":null,\"labelList\":[],\"descriptionEditor\":\"穿着校服的男孩和女孩，怎么看起来像在拍韩剧？这么想你就错了，这只是广告。男孩打篮球时穿的衣服上没有汗，被女孩认为骗了她，看到最后才发现是\\u2026\\u2026虽然男女主演技有点尴尬，但这个脑洞你不得不服啊。From 티몬 TMON Official\",\"collected\":false,\"played\":false,\"subtitles\":[],\"lastViewTime\":null,\"playlists\":null,\"src\":null},\"tag\":null,\"id\":0,\"adIndex\":-1},{\"type\":\"video\",\"data\":{\"dataType\":\"VideoBeanForClient\",\"id\":121761,\"title\":\"啪啪啪的时候，你有特别的癖好吗？\",\"description\":\"在做不可描述的事情时，你有什么特别的喜好？本片总结了诸多奇奇怪怪的性癖好，包括恋足癖、角色扮演等。性是美好的，每个人都想拥有与众不同的体验。为了满足彼此，玩点不一样的有何不可呢？\",\"library\":\"DAILY\",\"tags\":[{\"id\":128,\"name\":\"污\",\"actionUrl\":\"eyepetizer://tag/128/?title=%E6%B1%A1\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/4bb010aab06fe32397359def83e4e47c.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/5897def623ef2313849502049047dea1.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":484,\"name\":\"干货\",\"actionUrl\":\"eyepetizer://tag/484/?title=%E5%B9%B2%E8%B4%A7\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/27856a0c2855246c31c19f7a8fd814ce.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/27856a0c2855246c31c19f7a8fd814ce.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":556,\"name\":\"科技\",\"actionUrl\":\"eyepetizer://tag/556/?title=%E7%A7%91%E6%8A%80\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/27c3e861a02ced6069dd64c977746a61.jpeg?imageMogr2/quality/60\",\"headerImage\":\"http://img.kaiyanapp.com/b8a3443f9ff392b22201b74e47995e3c.jpeg?imageMogr2/quality/100\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null}],\"consumption\":{\"collectionCount\":128,\"shareCount\":50,\"replyCount\":10},\"resourceType\":\"video\",\"slogan\":\"别害羞，就知道你想看\",\"provider\":{\"name\":\"YouTube\",\"alias\":\"youtube\",\"icon\":\"http://img.kaiyanapp.com/fa20228bc5b921e837156923a58713f6.png\"},\"category\":\"科技\",\"author\":{\"id\":2539,\"icon\":\"http://img.kaiyanapp.com/619decaa6ba28afddcf7ad47ac78161d.jpeg?imageMogr2/quality/60/format/jpg\",\"name\":\"AsapSCIENCE\",\"description\":\"让科普变得更生动有趣～\",\"link\":\"\",\"latestReleaseTime\":1534640414000,\"videoNum\":6,\"adTrack\":null,\"follow\":{\"itemType\":\"author\",\"itemId\":2539,\"followed\":false},\"shield\":{\"itemType\":\"author\",\"itemId\":2539,\"shielded\":false},\"approvedNotReadyVideoCount\":0,\"ifPgc\":true},\"cover\":{\"feed\":\"http://img.kaiyanapp.com/59537fb3478f6987e1f07a91912422ca.jpeg?imageMogr2/quality/60/format/jpg\",\"detail\":\"http://img.kaiyanapp.com/59537fb3478f6987e1f07a91912422ca.jpeg?imageMogr2/quality/60/format/jpg\",\"blurred\":\"http://img.kaiyanapp.com/197f4c5c6843de58a6ffc4422fe3b268.jpeg?imageMogr2/quality/60/format/jpg\",\"sharing\":null,\"homepage\":\"http://img.kaiyanapp.com/59537fb3478f6987e1f07a91912422ca.jpeg?imageView2/1/w/720/h/560/format/jpg/q/75|watermark/1/image/aHR0cDovL2ltZy5rYWl5YW5hcHAuY29tL2JsYWNrXzMwLnBuZw==/dissolve/100/gravity/Center/dx/0/dy/0|imageslim\"},\"playUrl\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121761&resourceType=video&editionType=default&source=aliyun\",\"thumbPlayUrl\":null,\"duration\":217,\"webUrl\":{\"raw\":\"http://www.eyepetizer.net/detail.html?vid=121761\",\"forWeibo\":\"http://www.eyepetizer.net/detail.html?vid=121761&resourceType=video&utm_campaign=routine&utm_medium=share&utm_source=weibo&uid=0\"},\"releaseTime\":1534640414000,\"playInfo\":[{\"height\":480,\"width\":854,\"urlList\":[{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121761&resourceType=video&editionType=normal&source=aliyun\",\"size\":13753444},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121761&resourceType=video&editionType=normal&source=qcloud\",\"size\":13753444},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121761&resourceType=video&editionType=normal&source=ucloud\",\"size\":13753444}],\"name\":\"标清\",\"type\":\"normal\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121761&resourceType=video&editionType=normal&source=aliyun\"},{\"height\":720,\"width\":1280,\"urlList\":[{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121761&resourceType=video&editionType=high&source=aliyun\",\"size\":25563668},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121761&resourceType=video&editionType=high&source=qcloud\",\"size\":25563668},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121761&resourceType=video&editionType=high&source=ucloud\",\"size\":25563668}],\"name\":\"高清\",\"type\":\"high\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121761&resourceType=video&editionType=high&source=aliyun\"}],\"campaign\":null,\"waterMarks\":null,\"adTrack\":null,\"type\":\"NORMAL\",\"titlePgc\":null,\"descriptionPgc\":null,\"remark\":null,\"ifLimitVideo\":false,\"searchWeight\":0,\"idx\":0,\"shareAdTrack\":null,\"favoriteAdTrack\":null,\"webAdTrack\":null,\"date\":1534640400000,\"promotion\":null,\"label\":null,\"labelList\":[],\"descriptionEditor\":\"在做不可描述的事情时，你有什么特别的喜好？本片总结了诸多奇奇怪怪的性癖好，包括恋足癖、角色扮演等。性是美好的，每个人都想拥有与众不同的体验。为了满足彼此，玩点不一样的有何不可呢？\",\"collected\":false,\"played\":false,\"subtitles\":[],\"lastViewTime\":null,\"playlists\":null,\"src\":null},\"tag\":null,\"id\":0,\"adIndex\":-1},{\"type\":\"video\",\"data\":{\"dataType\":\"VideoBeanForClient\",\"id\":104218,\"title\":\"游戏画风短片：「橡皮糖危机」\",\"description\":\"本片讲述了一个空间燃气员 Ed 的故事，他必须克服各种障碍才能拯救他的家乡。在这次冒险中，市长要求埃德修复由敌人造成的煤气泄漏。敌人，一种名为 Lord Gasideous 的病毒，旨在通过在整个城市传播他的气体来控制每个人。最终他能拯救自己的家乡吗？From Blirp Studio \",\"library\":\"DAILY\",\"tags\":[{\"id\":14,\"name\":\"动画\",\"actionUrl\":\"eyepetizer://tag/14/?title=%E5%8A%A8%E7%94%BB\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/c4e5c0f76d21abbd23c9626af3c9f481.jpeg?imageMogr2/quality/100\",\"headerImage\":\"http://img.kaiyanapp.com/88da8548d31005032c37df4889d2104c.jpeg?imageMogr2/quality/100\",\"tagRecType\":\"IMPORTANT\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":204,\"name\":\"精致\",\"actionUrl\":\"eyepetizer://tag/204/?title=%E7%B2%BE%E8%87%B4\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/ee3a04688868510772ca7c30fdc7fce6.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/ee3a04688868510772ca7c30fdc7fce6.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":546,\"name\":\"宇宙\",\"actionUrl\":\"eyepetizer://tag/546/?title=%E5%AE%87%E5%AE%99\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/7052c0f6e4267111b023d2541b1a7f07.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/7052c0f6e4267111b023d2541b1a7f07.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null}],\"consumption\":{\"collectionCount\":257,\"shareCount\":83,\"replyCount\":7},\"resourceType\":\"video\",\"slogan\":\"我的地盘，由我来拯救！\",\"provider\":{\"name\":\"Vimeo\",\"alias\":\"vimeo\",\"icon\":\"http://img.kaiyanapp.com/c3ad630be461cbb081649c9e21d6cbe3.png\"},\"category\":\"动画\",\"author\":{\"id\":2170,\"icon\":\"http://img.kaiyanapp.com/482c741c06644f5566c7218096dbaf26.jpeg\",\"name\":\"开眼动画精选\",\"description\":\"有趣的人永远不缺童心\",\"link\":\"\",\"latestReleaseTime\":1534554004000,\"videoNum\":640,\"adTrack\":null,\"follow\":{\"itemType\":\"author\",\"itemId\":2170,\"followed\":false},\"shield\":{\"itemType\":\"author\",\"itemId\":2170,\"shielded\":false},\"approvedNotReadyVideoCount\":0,\"ifPgc\":true},\"cover\":{\"feed\":\"http://img.kaiyanapp.com/2e2cfa94b1984594b9195aea52f10a2e.jpeg?imageMogr2/quality/60/format/jpg\",\"detail\":\"http://img.kaiyanapp.com/2e2cfa94b1984594b9195aea52f10a2e.jpeg?imageMogr2/quality/60/format/jpg\",\"blurred\":\"http://img.kaiyanapp.com/7dc07b6e75bec8582273d02e669e0fb7.jpeg?imageMogr2/quality/60/format/jpg\",\"sharing\":null,\"homepage\":\"http://img.kaiyanapp.com/2e2cfa94b1984594b9195aea52f10a2e.jpeg?imageView2/1/w/720/h/560/format/jpg/q/75|watermark/1/image/aHR0cDovL2ltZy5rYWl5YW5hcHAuY29tL2JsYWNrXzMwLnBuZw==/dissolve/100/gravity/Center/dx/0/dy/0|imageslim\"},\"playUrl\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=104218&resourceType=video&editionType=default&source=aliyun\",\"thumbPlayUrl\":null,\"duration\":204,\"webUrl\":{\"raw\":\"http://www.eyepetizer.net/detail.html?vid=104218\",\"forWeibo\":\"http://www.eyepetizer.net/detail.html?vid=104218\"},\"releaseTime\":1526629513000,\"playInfo\":[{\"height\":480,\"width\":854,\"urlList\":[{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=104218&resourceType=video&editionType=normal&source=aliyun\",\"size\":24269530},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=104218&resourceType=video&editionType=normal&source=qcloud\",\"size\":24269530},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=104218&resourceType=video&editionType=normal&source=ucloud\",\"size\":24269530}],\"name\":\"标清\",\"type\":\"normal\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=104218&resourceType=video&editionType=normal&source=aliyun\"},{\"height\":720,\"width\":1280,\"urlList\":[{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=104218&resourceType=video&editionType=high&source=aliyun\",\"size\":40246985},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=104218&resourceType=video&editionType=high&source=qcloud\",\"size\":40246985},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=104218&resourceType=video&editionType=high&source=ucloud\",\"size\":40246985}],\"name\":\"高清\",\"type\":\"high\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=104218&resourceType=video&editionType=high&source=aliyun\"}],\"campaign\":null,\"waterMarks\":null,\"adTrack\":null,\"type\":\"NORMAL\",\"titlePgc\":null,\"descriptionPgc\":null,\"remark\":null,\"ifLimitVideo\":false,\"searchWeight\":0,\"idx\":0,\"shareAdTrack\":null,\"favoriteAdTrack\":null,\"webAdTrack\":null,\"date\":1534640400000,\"promotion\":null,\"label\":null,\"labelList\":[],\"descriptionEditor\":\"本片讲述了一个空间燃气员 Ed 的故事，他必须克服各种障碍才能拯救他的家乡。在这次冒险中，市长要求埃德修复由敌人造成的煤气泄漏。敌人，一种名为 Lord Gasideous 的病毒，旨在通过在整个城市传播他的气体来控制每个人。最终他能拯救自己的家乡吗？From Blirp Studio \",\"collected\":false,\"played\":false,\"subtitles\":[],\"lastViewTime\":null,\"playlists\":null,\"src\":null},\"tag\":null,\"id\":0,\"adIndex\":-1},{\"type\":\"video\",\"data\":{\"dataType\":\"VideoBeanForClient\",\"id\":112909,\"title\":\"世界那么大，只需活在当下\",\"description\":\"看多了手机上的风光，你会觉得这个世界也就如此，要是离开手机，你会怎么办？有句台词叫「真实自有其力量」，在说这句话的时候，主人公眼神放光，我想他想看的该是没 P 过的世界吧。From Motion Craft\",\"library\":\"DAILY\",\"tags\":[{\"id\":10,\"name\":\"旅行\",\"actionUrl\":\"eyepetizer://tag/10/?title=%E6%97%85%E8%A1%8C\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/c1e1357770cc194272e735f3b1469868.jpeg?imageMogr2/quality/100\",\"headerImage\":\"http://img.kaiyanapp.com/8ff732f275759b2cb3a0b7fc9ba1715f.jpeg?imageMogr2/quality/100\",\"tagRecType\":\"IMPORTANT\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":34,\"name\":\"混剪\",\"actionUrl\":\"eyepetizer://tag/34/?title=%E6%B7%B7%E5%89%AA\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/ebf307197b634f30b2fa4eb867e908c1.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/ebf307197b634f30b2fa4eb867e908c1.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":52,\"name\":\"风光摄影\",\"actionUrl\":\"eyepetizer://tag/52/?title=%E9%A3%8E%E5%85%89%E6%91%84%E5%BD%B1\",\"adTrack\":null,\"desc\":\"\",\"bgPicture\":\"http://img.kaiyanapp.com/1d8a845e9def7b9af2e947afc858ee18.jpeg?imageMogr2/quality/100\",\"headerImage\":\"http://img.kaiyanapp.com/1d8a845e9def7b9af2e947afc858ee18.jpeg?imageMogr2/quality/100\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null}],\"consumption\":{\"collectionCount\":1143,\"shareCount\":749,\"replyCount\":12},\"resourceType\":\"video\",\"slogan\":\"没有「滤镜」过的世界就很美\",\"provider\":{\"name\":\"Vimeo\",\"alias\":\"vimeo\",\"icon\":\"http://img.kaiyanapp.com/c3ad630be461cbb081649c9e21d6cbe3.png\"},\"category\":\"旅行\",\"author\":{\"id\":2164,\"icon\":\"http://img.kaiyanapp.com/75bc791c5f6cc239d6056e0a52d077fd.jpeg?imageMogr2/quality/60/format/jpg\",\"name\":\"开眼旅行精选\",\"description\":\"发现世界的奇妙和辽阔\",\"link\":\"\",\"latestReleaseTime\":1534122011000,\"videoNum\":502,\"adTrack\":null,\"follow\":{\"itemType\":\"author\",\"itemId\":2164,\"followed\":false},\"shield\":{\"itemType\":\"author\",\"itemId\":2164,\"shielded\":false},\"approvedNotReadyVideoCount\":0,\"ifPgc\":true},\"cover\":{\"feed\":\"http://img.kaiyanapp.com/54680c20ac916565a8cfbee1d4135a2b.png?imageMogr2/quality/60/format/jpg\",\"detail\":\"http://img.kaiyanapp.com/54680c20ac916565a8cfbee1d4135a2b.png?imageMogr2/quality/60/format/jpg\",\"blurred\":\"http://img.kaiyanapp.com/8690d3989e38acae4d7efe0cbaea59e1.png?imageMogr2/quality/60/format/jpg\",\"sharing\":null,\"homepage\":\"http://img.kaiyanapp.com/54680c20ac916565a8cfbee1d4135a2b.png?imageView2/1/w/720/h/560/format/jpg/q/75|watermark/1/image/aHR0cDovL2ltZy5rYWl5YW5hcHAuY29tL2JsYWNrXzMwLnBuZw==/dissolve/100/gravity/Center/dx/0/dy/0|imageslim\"},\"playUrl\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=112909&resourceType=video&editionType=default&source=aliyun\",\"thumbPlayUrl\":null,\"duration\":109,\"webUrl\":{\"raw\":\"http://www.eyepetizer.net/detail.html?vid=112909\",\"forWeibo\":\"http://www.eyepetizer.net/detail.html?vid=112909\"},\"releaseTime\":1532711225000,\"playInfo\":[{\"height\":480,\"width\":854,\"urlList\":[{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=112909&resourceType=video&editionType=normal&source=aliyun\",\"size\":20044741},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=112909&resourceType=video&editionType=normal&source=qcloud\",\"size\":20044741},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=112909&resourceType=video&editionType=normal&source=ucloud\",\"size\":20044741}],\"name\":\"标清\",\"type\":\"normal\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=112909&resourceType=video&editionType=normal&source=aliyun\"},{\"height\":720,\"width\":1280,\"urlList\":[{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=112909&resourceType=video&editionType=high&source=aliyun\",\"size\":32944056},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=112909&resourceType=video&editionType=high&source=qcloud\",\"size\":32944056},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=112909&resourceType=video&editionType=high&source=ucloud\",\"size\":32944056}],\"name\":\"高清\",\"type\":\"high\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=112909&resourceType=video&editionType=high&source=aliyun\"}],\"campaign\":null,\"waterMarks\":null,\"adTrack\":null,\"type\":\"NORMAL\",\"titlePgc\":null,\"descriptionPgc\":null,\"remark\":null,\"ifLimitVideo\":false,\"searchWeight\":0,\"idx\":0,\"shareAdTrack\":null,\"favoriteAdTrack\":null,\"webAdTrack\":null,\"date\":1534640400000,\"promotion\":null,\"label\":null,\"labelList\":[],\"descriptionEditor\":\"看多了手机上的风光，你会觉得这个世界也就如此，要是离开手机，你会怎么办？有句台词叫「真实自有其力量」，在说这句话的时候，主人公眼神放光，我想他想看的该是没 P 过的世界吧。From Motion Craft\",\"collected\":false,\"played\":false,\"subtitles\":[],\"lastViewTime\":null,\"playlists\":null,\"src\":null},\"tag\":null,\"id\":0,\"adIndex\":-1}],\"count\":5}]\n     * nextPageUrl : http://baobab.kaiyanapp.com/api/v2/feed?date=1534554000000&num=1\n     * nextPublishTime : 1534726800000\n     * newestIssueType : morning\n     * dialog : null\n     */\n\n    private String nextPageUrl;\n    private long nextPublishTime;\n    private String newestIssueType;\n    private Object dialog;\n    private List<IssueList> issueList;\n\n    public String getNextPageUrl() {\n        return nextPageUrl;\n    }\n\n    public void setNextPageUrl(String nextPageUrl) {\n        this.nextPageUrl = nextPageUrl;\n    }\n\n    public long getNextPublishTime() {\n        return nextPublishTime;\n    }\n\n    public void setNextPublishTime(long nextPublishTime) {\n        this.nextPublishTime = nextPublishTime;\n    }\n\n    public String getNewestIssueType() {\n        return newestIssueType;\n    }\n\n    public void setNewestIssueType(String newestIssueType) {\n        this.newestIssueType = newestIssueType;\n    }\n\n    public Object getDialog() {\n        return dialog;\n    }\n\n    public void setDialog(Object dialog) {\n        this.dialog = dialog;\n    }\n\n    public List<IssueList> getIssueList() {\n        return issueList;\n    }\n\n    public void setIssueList(List<IssueList> issueList) {\n        this.issueList = issueList;\n    }\n\n    public static class IssueList {\n        /**\n         * releaseTime : 1534640400000\n         * type : morning\n         * date : 1534640400000\n         * publishTime : 1534640400000\n         * itemList : [{\"type\":\"video\",\"data\":{\"dataType\":\"VideoBeanForClient\",\"id\":122208,\"title\":\"致敬经典：当吉卜力动画走进现实\",\"description\":\"本片作者是来自韩国的 Kojer，他将吉卜力工作室耳熟能详的动画人物「放」进了真实的世界中，竟毫无违和感。有「千与千寻」、「龙猫」和「天空之城」等，你最爱的是哪一个场景？From Sunflower12\",\"library\":\"DAILY\",\"tags\":[{\"id\":470,\"name\":\"吉卜力\",\"actionUrl\":\"eyepetizer://tag/470/?title=%E5%90%89%E5%8D%9C%E5%8A%9B\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/2d50274d224680bf06d3062d6874482b.jpeg?imageMogr2/quality/60\",\"headerImage\":\"http://img.kaiyanapp.com/2d50274d224680bf06d3062d6874482b.jpeg?imageMogr2/quality/60\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":570,\"name\":\"电影相关\",\"actionUrl\":\"eyepetizer://tag/570/?title=%E7%94%B5%E5%BD%B1%E7%9B%B8%E5%85%B3\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/bee7c0cd647345f911c10be60ffcde93.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/bee7c0cd647345f911c10be60ffcde93.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":506,\"name\":\"经典\",\"actionUrl\":\"eyepetizer://tag/506/?title=%E7%BB%8F%E5%85%B8\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/1e948eab70737d8beca9f52fce907ab5.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/1e948eab70737d8beca9f52fce907ab5.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":424,\"name\":\"宫崎骏\",\"actionUrl\":\"eyepetizer://tag/424/?title=%E5%AE%AB%E5%B4%8E%E9%AA%8F\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/00f9596704c7eeb7ef65d095b453c8b3.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/00f9596704c7eeb7ef65d095b453c8b3.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":749,\"name\":\"影视周边\",\"actionUrl\":\"eyepetizer://tag/749/?title=%E5%BD%B1%E8%A7%86%E5%91%A8%E8%BE%B9\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/787bc5416e2a985520834eafa9d132af.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/787bc5416e2a985520834eafa9d132af.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null}],\"consumption\":{\"collectionCount\":1000,\"shareCount\":641,\"replyCount\":33},\"resourceType\":\"video\",\"slogan\":\"世界瞬间变成令人感动的童话乐园\",\"provider\":{\"name\":\"YouTube\",\"alias\":\"youtube\",\"icon\":\"http://img.kaiyanapp.com/fa20228bc5b921e837156923a58713f6.png\"},\"category\":\"影视\",\"author\":{\"id\":2173,\"icon\":\"http://img.kaiyanapp.com/003829087e85ce7310b2210d9575ce67.jpeg\",\"name\":\"开眼影视精选\",\"description\":\"关于电影、剧集的一切\",\"link\":\"\",\"latestReleaseTime\":1534640409000,\"videoNum\":442,\"adTrack\":null,\"follow\":{\"itemType\":\"author\",\"itemId\":2173,\"followed\":false},\"shield\":{\"itemType\":\"author\",\"itemId\":2173,\"shielded\":false},\"approvedNotReadyVideoCount\":0,\"ifPgc\":true},\"cover\":{\"feed\":\"http://img.kaiyanapp.com/11f42b2135bb7553b144f5fc7111a56f.jpeg?imageMogr2/quality/60/format/jpg\",\"detail\":\"http://img.kaiyanapp.com/11f42b2135bb7553b144f5fc7111a56f.jpeg?imageMogr2/quality/60/format/jpg\",\"blurred\":\"http://img.kaiyanapp.com/a7399848cb61d7ea2e7707050cc7b243.jpeg?imageMogr2/quality/60/format/jpg\",\"sharing\":null,\"homepage\":\"http://img.kaiyanapp.com/11f42b2135bb7553b144f5fc7111a56f.jpeg?imageView2/1/w/720/h/560/format/jpg/q/75|watermark/1/image/aHR0cDovL2ltZy5rYWl5YW5hcHAuY29tL2JsYWNrXzMwLnBuZw==/dissolve/100/gravity/Center/dx/0/dy/0|imageslim\"},\"playUrl\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=default&source=aliyun\",\"thumbPlayUrl\":null,\"duration\":220,\"webUrl\":{\"raw\":\"http://www.eyepetizer.net/detail.html?vid=122208\",\"forWeibo\":\"http://www.eyepetizer.net/detail.html?vid=122208&resourceType=video&utm_campaign=routine&utm_medium=share&utm_source=weibo&uid=0\"},\"releaseTime\":1534640409000,\"playInfo\":[{\"height\":480,\"width\":854,\"urlList\":[{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=normal&source=aliyun\",\"size\":25152959},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=normal&source=qcloud\",\"size\":25152959},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=normal&source=ucloud\",\"size\":25152959}],\"name\":\"标清\",\"type\":\"normal\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=normal&source=aliyun\"},{\"height\":720,\"width\":1280,\"urlList\":[{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=high&source=aliyun\",\"size\":36837465},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=high&source=qcloud\",\"size\":36837465},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=high&source=ucloud\",\"size\":36837465}],\"name\":\"高清\",\"type\":\"high\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=high&source=aliyun\"}],\"campaign\":null,\"waterMarks\":null,\"adTrack\":null,\"type\":\"NORMAL\",\"titlePgc\":null,\"descriptionPgc\":null,\"remark\":null,\"ifLimitVideo\":false,\"searchWeight\":0,\"idx\":0,\"shareAdTrack\":null,\"favoriteAdTrack\":null,\"webAdTrack\":null,\"date\":1534640400000,\"promotion\":null,\"label\":null,\"labelList\":[],\"descriptionEditor\":\"本片作者是来自韩国的 Kojer，他将吉卜力工作室耳熟能详的动画人物「放」进了真实的世界中，竟毫无违和感。有「千与千寻」、「龙猫」和「天空之城」等，你最爱的是哪一个场景？From Sunflower12\",\"collected\":false,\"played\":false,\"subtitles\":[],\"lastViewTime\":null,\"playlists\":null,\"src\":null},\"tag\":null,\"id\":0,\"adIndex\":-1},{\"type\":\"video\",\"data\":{\"dataType\":\"VideoBeanForClient\",\"id\":121783,\"title\":\"韩国反套路广告：高中生的爱情\",\"description\":\"穿着校服的男孩和女孩，怎么看起来像在拍韩剧？这么想你就错了，这只是广告。男孩打篮球时穿的衣服上没有汗，被女孩认为骗了她，看到最后才发现是\\u2026\\u2026虽然男女主演技有点尴尬，但这个脑洞你不得不服啊。From 티몬 TMON Official\",\"library\":\"DAILY\",\"tags\":[{\"id\":748,\"name\":\"广告精选\",\"actionUrl\":\"eyepetizer://tag/748/?title=%E5%B9%BF%E5%91%8A%E7%B2%BE%E9%80%89\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/431177a6b2177788aa4d8eff8073d9a7.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/431177a6b2177788aa4d8eff8073d9a7.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"IMPORTANT\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":504,\"name\":\"笑cry\",\"actionUrl\":\"eyepetizer://tag/504/?title=%E7%AC%91cry\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/3d3cb19d13cc16e8c3c2eddb12284fa3.jpeg?imageMogr2/quality/100\",\"headerImage\":\"http://img.kaiyanapp.com/177986653f12273f6d55edafe856ffe3.jpeg?imageMogr2/quality/100\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":150,\"name\":\"青春\",\"actionUrl\":\"eyepetizer://tag/150/?title=%E9%9D%92%E6%98%A5\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/34d33f611dbfe38e4d00cd4ab43212e7.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/58e3e0ec1e583a6debcc0f80d16c86fe.jpeg?imageMogr2/quality/100\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":108,\"name\":\"爱情\",\"actionUrl\":\"eyepetizer://tag/108/?title=%E7%88%B1%E6%83%85\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/67025fb5bf4f8ff4ccd63cdcfd0cd6c6.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/67025fb5bf4f8ff4ccd63cdcfd0cd6c6.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":16,\"name\":\"广告\",\"actionUrl\":\"eyepetizer://tag/16/?title=%E5%B9%BF%E5%91%8A\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/e41e74fe73882b552de00d95d56748d2.jpeg?imageMogr2/quality/60\",\"headerImage\":\"http://img.kaiyanapp.com/3054658dbd559ac42c4c282e9cab7a32.jpeg?imageMogr2/quality/100\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null}],\"consumption\":{\"collectionCount\":128,\"shareCount\":103,\"replyCount\":20},\"resourceType\":\"video\",\"slogan\":\"偶像剧包装下的清奇脑回路\",\"provider\":{\"name\":\"YouTube\",\"alias\":\"youtube\",\"icon\":\"http://img.kaiyanapp.com/fa20228bc5b921e837156923a58713f6.png\"},\"category\":\"广告\",\"author\":{\"id\":2162,\"icon\":\"http://img.kaiyanapp.com/98beab66d3885a139b54f21e91817c4f.jpeg\",\"name\":\"开眼广告精选\",\"description\":\"为广告人的精彩创意点赞\",\"link\":\"\",\"latestReleaseTime\":1534640412000,\"videoNum\":1000,\"adTrack\":null,\"follow\":{\"itemType\":\"author\",\"itemId\":2162,\"followed\":false},\"shield\":{\"itemType\":\"author\",\"itemId\":2162,\"shielded\":false},\"approvedNotReadyVideoCount\":0,\"ifPgc\":true},\"cover\":{\"feed\":\"http://img.kaiyanapp.com/699d698e9c6a210453bf6785dc75d80a.png?imageMogr2/quality/60/format/jpg\",\"detail\":\"http://img.kaiyanapp.com/699d698e9c6a210453bf6785dc75d80a.png?imageMogr2/quality/60/format/jpg\",\"blurred\":\"http://img.kaiyanapp.com/247f776b9d2ac64e489ac676c67600cb.png?imageMogr2/quality/60/format/jpg\",\"sharing\":null,\"homepage\":\"http://img.kaiyanapp.com/699d698e9c6a210453bf6785dc75d80a.png?imageView2/1/w/720/h/560/format/jpg/q/75|watermark/1/image/aHR0cDovL2ltZy5rYWl5YW5hcHAuY29tL2JsYWNrXzMwLnBuZw==/dissolve/100/gravity/Center/dx/0/dy/0|imageslim\"},\"playUrl\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121783&resourceType=video&editionType=default&source=aliyun\",\"thumbPlayUrl\":null,\"duration\":206,\"webUrl\":{\"raw\":\"http://www.eyepetizer.net/detail.html?vid=121783\",\"forWeibo\":\"http://www.eyepetizer.net/detail.html?vid=121783&resourceType=video&utm_campaign=routine&utm_medium=share&utm_source=weibo&uid=0\"},\"releaseTime\":1534640412000,\"playInfo\":[{\"height\":480,\"width\":854,\"urlList\":[{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121783&resourceType=video&editionType=normal&source=aliyun\",\"size\":10596486},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121783&resourceType=video&editionType=normal&source=qcloud\",\"size\":10596486},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121783&resourceType=video&editionType=normal&source=ucloud\",\"size\":10596486}],\"name\":\"标清\",\"type\":\"normal\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121783&resourceType=video&editionType=normal&source=aliyun\"},{\"height\":720,\"width\":1280,\"urlList\":[{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121783&resourceType=video&editionType=high&source=aliyun\",\"size\":21560023},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121783&resourceType=video&editionType=high&source=qcloud\",\"size\":21560023},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121783&resourceType=video&editionType=high&source=ucloud\",\"size\":21560023}],\"name\":\"高清\",\"type\":\"high\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121783&resourceType=video&editionType=high&source=aliyun\"}],\"campaign\":null,\"waterMarks\":null,\"adTrack\":null,\"type\":\"NORMAL\",\"titlePgc\":null,\"descriptionPgc\":null,\"remark\":null,\"ifLimitVideo\":false,\"searchWeight\":0,\"idx\":0,\"shareAdTrack\":null,\"favoriteAdTrack\":null,\"webAdTrack\":null,\"date\":1534640400000,\"promotion\":null,\"label\":null,\"labelList\":[],\"descriptionEditor\":\"穿着校服的男孩和女孩，怎么看起来像在拍韩剧？这么想你就错了，这只是广告。男孩打篮球时穿的衣服上没有汗，被女孩认为骗了她，看到最后才发现是\\u2026\\u2026虽然男女主演技有点尴尬，但这个脑洞你不得不服啊。From 티몬 TMON Official\",\"collected\":false,\"played\":false,\"subtitles\":[],\"lastViewTime\":null,\"playlists\":null,\"src\":null},\"tag\":null,\"id\":0,\"adIndex\":-1},{\"type\":\"video\",\"data\":{\"dataType\":\"VideoBeanForClient\",\"id\":121761,\"title\":\"啪啪啪的时候，你有特别的癖好吗？\",\"description\":\"在做不可描述的事情时，你有什么特别的喜好？本片总结了诸多奇奇怪怪的性癖好，包括恋足癖、角色扮演等。性是美好的，每个人都想拥有与众不同的体验。为了满足彼此，玩点不一样的有何不可呢？\",\"library\":\"DAILY\",\"tags\":[{\"id\":128,\"name\":\"污\",\"actionUrl\":\"eyepetizer://tag/128/?title=%E6%B1%A1\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/4bb010aab06fe32397359def83e4e47c.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/5897def623ef2313849502049047dea1.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":484,\"name\":\"干货\",\"actionUrl\":\"eyepetizer://tag/484/?title=%E5%B9%B2%E8%B4%A7\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/27856a0c2855246c31c19f7a8fd814ce.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/27856a0c2855246c31c19f7a8fd814ce.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":556,\"name\":\"科技\",\"actionUrl\":\"eyepetizer://tag/556/?title=%E7%A7%91%E6%8A%80\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/27c3e861a02ced6069dd64c977746a61.jpeg?imageMogr2/quality/60\",\"headerImage\":\"http://img.kaiyanapp.com/b8a3443f9ff392b22201b74e47995e3c.jpeg?imageMogr2/quality/100\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null}],\"consumption\":{\"collectionCount\":128,\"shareCount\":50,\"replyCount\":10},\"resourceType\":\"video\",\"slogan\":\"别害羞，就知道你想看\",\"provider\":{\"name\":\"YouTube\",\"alias\":\"youtube\",\"icon\":\"http://img.kaiyanapp.com/fa20228bc5b921e837156923a58713f6.png\"},\"category\":\"科技\",\"author\":{\"id\":2539,\"icon\":\"http://img.kaiyanapp.com/619decaa6ba28afddcf7ad47ac78161d.jpeg?imageMogr2/quality/60/format/jpg\",\"name\":\"AsapSCIENCE\",\"description\":\"让科普变得更生动有趣～\",\"link\":\"\",\"latestReleaseTime\":1534640414000,\"videoNum\":6,\"adTrack\":null,\"follow\":{\"itemType\":\"author\",\"itemId\":2539,\"followed\":false},\"shield\":{\"itemType\":\"author\",\"itemId\":2539,\"shielded\":false},\"approvedNotReadyVideoCount\":0,\"ifPgc\":true},\"cover\":{\"feed\":\"http://img.kaiyanapp.com/59537fb3478f6987e1f07a91912422ca.jpeg?imageMogr2/quality/60/format/jpg\",\"detail\":\"http://img.kaiyanapp.com/59537fb3478f6987e1f07a91912422ca.jpeg?imageMogr2/quality/60/format/jpg\",\"blurred\":\"http://img.kaiyanapp.com/197f4c5c6843de58a6ffc4422fe3b268.jpeg?imageMogr2/quality/60/format/jpg\",\"sharing\":null,\"homepage\":\"http://img.kaiyanapp.com/59537fb3478f6987e1f07a91912422ca.jpeg?imageView2/1/w/720/h/560/format/jpg/q/75|watermark/1/image/aHR0cDovL2ltZy5rYWl5YW5hcHAuY29tL2JsYWNrXzMwLnBuZw==/dissolve/100/gravity/Center/dx/0/dy/0|imageslim\"},\"playUrl\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121761&resourceType=video&editionType=default&source=aliyun\",\"thumbPlayUrl\":null,\"duration\":217,\"webUrl\":{\"raw\":\"http://www.eyepetizer.net/detail.html?vid=121761\",\"forWeibo\":\"http://www.eyepetizer.net/detail.html?vid=121761&resourceType=video&utm_campaign=routine&utm_medium=share&utm_source=weibo&uid=0\"},\"releaseTime\":1534640414000,\"playInfo\":[{\"height\":480,\"width\":854,\"urlList\":[{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121761&resourceType=video&editionType=normal&source=aliyun\",\"size\":13753444},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121761&resourceType=video&editionType=normal&source=qcloud\",\"size\":13753444},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121761&resourceType=video&editionType=normal&source=ucloud\",\"size\":13753444}],\"name\":\"标清\",\"type\":\"normal\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121761&resourceType=video&editionType=normal&source=aliyun\"},{\"height\":720,\"width\":1280,\"urlList\":[{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121761&resourceType=video&editionType=high&source=aliyun\",\"size\":25563668},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121761&resourceType=video&editionType=high&source=qcloud\",\"size\":25563668},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121761&resourceType=video&editionType=high&source=ucloud\",\"size\":25563668}],\"name\":\"高清\",\"type\":\"high\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=121761&resourceType=video&editionType=high&source=aliyun\"}],\"campaign\":null,\"waterMarks\":null,\"adTrack\":null,\"type\":\"NORMAL\",\"titlePgc\":null,\"descriptionPgc\":null,\"remark\":null,\"ifLimitVideo\":false,\"searchWeight\":0,\"idx\":0,\"shareAdTrack\":null,\"favoriteAdTrack\":null,\"webAdTrack\":null,\"date\":1534640400000,\"promotion\":null,\"label\":null,\"labelList\":[],\"descriptionEditor\":\"在做不可描述的事情时，你有什么特别的喜好？本片总结了诸多奇奇怪怪的性癖好，包括恋足癖、角色扮演等。性是美好的，每个人都想拥有与众不同的体验。为了满足彼此，玩点不一样的有何不可呢？\",\"collected\":false,\"played\":false,\"subtitles\":[],\"lastViewTime\":null,\"playlists\":null,\"src\":null},\"tag\":null,\"id\":0,\"adIndex\":-1},{\"type\":\"video\",\"data\":{\"dataType\":\"VideoBeanForClient\",\"id\":104218,\"title\":\"游戏画风短片：「橡皮糖危机」\",\"description\":\"本片讲述了一个空间燃气员 Ed 的故事，他必须克服各种障碍才能拯救他的家乡。在这次冒险中，市长要求埃德修复由敌人造成的煤气泄漏。敌人，一种名为 Lord Gasideous 的病毒，旨在通过在整个城市传播他的气体来控制每个人。最终他能拯救自己的家乡吗？From Blirp Studio \",\"library\":\"DAILY\",\"tags\":[{\"id\":14,\"name\":\"动画\",\"actionUrl\":\"eyepetizer://tag/14/?title=%E5%8A%A8%E7%94%BB\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/c4e5c0f76d21abbd23c9626af3c9f481.jpeg?imageMogr2/quality/100\",\"headerImage\":\"http://img.kaiyanapp.com/88da8548d31005032c37df4889d2104c.jpeg?imageMogr2/quality/100\",\"tagRecType\":\"IMPORTANT\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":204,\"name\":\"精致\",\"actionUrl\":\"eyepetizer://tag/204/?title=%E7%B2%BE%E8%87%B4\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/ee3a04688868510772ca7c30fdc7fce6.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/ee3a04688868510772ca7c30fdc7fce6.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":546,\"name\":\"宇宙\",\"actionUrl\":\"eyepetizer://tag/546/?title=%E5%AE%87%E5%AE%99\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/7052c0f6e4267111b023d2541b1a7f07.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/7052c0f6e4267111b023d2541b1a7f07.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null}],\"consumption\":{\"collectionCount\":257,\"shareCount\":83,\"replyCount\":7},\"resourceType\":\"video\",\"slogan\":\"我的地盘，由我来拯救！\",\"provider\":{\"name\":\"Vimeo\",\"alias\":\"vimeo\",\"icon\":\"http://img.kaiyanapp.com/c3ad630be461cbb081649c9e21d6cbe3.png\"},\"category\":\"动画\",\"author\":{\"id\":2170,\"icon\":\"http://img.kaiyanapp.com/482c741c06644f5566c7218096dbaf26.jpeg\",\"name\":\"开眼动画精选\",\"description\":\"有趣的人永远不缺童心\",\"link\":\"\",\"latestReleaseTime\":1534554004000,\"videoNum\":640,\"adTrack\":null,\"follow\":{\"itemType\":\"author\",\"itemId\":2170,\"followed\":false},\"shield\":{\"itemType\":\"author\",\"itemId\":2170,\"shielded\":false},\"approvedNotReadyVideoCount\":0,\"ifPgc\":true},\"cover\":{\"feed\":\"http://img.kaiyanapp.com/2e2cfa94b1984594b9195aea52f10a2e.jpeg?imageMogr2/quality/60/format/jpg\",\"detail\":\"http://img.kaiyanapp.com/2e2cfa94b1984594b9195aea52f10a2e.jpeg?imageMogr2/quality/60/format/jpg\",\"blurred\":\"http://img.kaiyanapp.com/7dc07b6e75bec8582273d02e669e0fb7.jpeg?imageMogr2/quality/60/format/jpg\",\"sharing\":null,\"homepage\":\"http://img.kaiyanapp.com/2e2cfa94b1984594b9195aea52f10a2e.jpeg?imageView2/1/w/720/h/560/format/jpg/q/75|watermark/1/image/aHR0cDovL2ltZy5rYWl5YW5hcHAuY29tL2JsYWNrXzMwLnBuZw==/dissolve/100/gravity/Center/dx/0/dy/0|imageslim\"},\"playUrl\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=104218&resourceType=video&editionType=default&source=aliyun\",\"thumbPlayUrl\":null,\"duration\":204,\"webUrl\":{\"raw\":\"http://www.eyepetizer.net/detail.html?vid=104218\",\"forWeibo\":\"http://www.eyepetizer.net/detail.html?vid=104218\"},\"releaseTime\":1526629513000,\"playInfo\":[{\"height\":480,\"width\":854,\"urlList\":[{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=104218&resourceType=video&editionType=normal&source=aliyun\",\"size\":24269530},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=104218&resourceType=video&editionType=normal&source=qcloud\",\"size\":24269530},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=104218&resourceType=video&editionType=normal&source=ucloud\",\"size\":24269530}],\"name\":\"标清\",\"type\":\"normal\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=104218&resourceType=video&editionType=normal&source=aliyun\"},{\"height\":720,\"width\":1280,\"urlList\":[{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=104218&resourceType=video&editionType=high&source=aliyun\",\"size\":40246985},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=104218&resourceType=video&editionType=high&source=qcloud\",\"size\":40246985},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=104218&resourceType=video&editionType=high&source=ucloud\",\"size\":40246985}],\"name\":\"高清\",\"type\":\"high\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=104218&resourceType=video&editionType=high&source=aliyun\"}],\"campaign\":null,\"waterMarks\":null,\"adTrack\":null,\"type\":\"NORMAL\",\"titlePgc\":null,\"descriptionPgc\":null,\"remark\":null,\"ifLimitVideo\":false,\"searchWeight\":0,\"idx\":0,\"shareAdTrack\":null,\"favoriteAdTrack\":null,\"webAdTrack\":null,\"date\":1534640400000,\"promotion\":null,\"label\":null,\"labelList\":[],\"descriptionEditor\":\"本片讲述了一个空间燃气员 Ed 的故事，他必须克服各种障碍才能拯救他的家乡。在这次冒险中，市长要求埃德修复由敌人造成的煤气泄漏。敌人，一种名为 Lord Gasideous 的病毒，旨在通过在整个城市传播他的气体来控制每个人。最终他能拯救自己的家乡吗？From Blirp Studio \",\"collected\":false,\"played\":false,\"subtitles\":[],\"lastViewTime\":null,\"playlists\":null,\"src\":null},\"tag\":null,\"id\":0,\"adIndex\":-1},{\"type\":\"video\",\"data\":{\"dataType\":\"VideoBeanForClient\",\"id\":112909,\"title\":\"世界那么大，只需活在当下\",\"description\":\"看多了手机上的风光，你会觉得这个世界也就如此，要是离开手机，你会怎么办？有句台词叫「真实自有其力量」，在说这句话的时候，主人公眼神放光，我想他想看的该是没 P 过的世界吧。From Motion Craft\",\"library\":\"DAILY\",\"tags\":[{\"id\":10,\"name\":\"旅行\",\"actionUrl\":\"eyepetizer://tag/10/?title=%E6%97%85%E8%A1%8C\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/c1e1357770cc194272e735f3b1469868.jpeg?imageMogr2/quality/100\",\"headerImage\":\"http://img.kaiyanapp.com/8ff732f275759b2cb3a0b7fc9ba1715f.jpeg?imageMogr2/quality/100\",\"tagRecType\":\"IMPORTANT\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":34,\"name\":\"混剪\",\"actionUrl\":\"eyepetizer://tag/34/?title=%E6%B7%B7%E5%89%AA\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/ebf307197b634f30b2fa4eb867e908c1.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/ebf307197b634f30b2fa4eb867e908c1.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":52,\"name\":\"风光摄影\",\"actionUrl\":\"eyepetizer://tag/52/?title=%E9%A3%8E%E5%85%89%E6%91%84%E5%BD%B1\",\"adTrack\":null,\"desc\":\"\",\"bgPicture\":\"http://img.kaiyanapp.com/1d8a845e9def7b9af2e947afc858ee18.jpeg?imageMogr2/quality/100\",\"headerImage\":\"http://img.kaiyanapp.com/1d8a845e9def7b9af2e947afc858ee18.jpeg?imageMogr2/quality/100\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null}],\"consumption\":{\"collectionCount\":1143,\"shareCount\":749,\"replyCount\":12},\"resourceType\":\"video\",\"slogan\":\"没有「滤镜」过的世界就很美\",\"provider\":{\"name\":\"Vimeo\",\"alias\":\"vimeo\",\"icon\":\"http://img.kaiyanapp.com/c3ad630be461cbb081649c9e21d6cbe3.png\"},\"category\":\"旅行\",\"author\":{\"id\":2164,\"icon\":\"http://img.kaiyanapp.com/75bc791c5f6cc239d6056e0a52d077fd.jpeg?imageMogr2/quality/60/format/jpg\",\"name\":\"开眼旅行精选\",\"description\":\"发现世界的奇妙和辽阔\",\"link\":\"\",\"latestReleaseTime\":1534122011000,\"videoNum\":502,\"adTrack\":null,\"follow\":{\"itemType\":\"author\",\"itemId\":2164,\"followed\":false},\"shield\":{\"itemType\":\"author\",\"itemId\":2164,\"shielded\":false},\"approvedNotReadyVideoCount\":0,\"ifPgc\":true},\"cover\":{\"feed\":\"http://img.kaiyanapp.com/54680c20ac916565a8cfbee1d4135a2b.png?imageMogr2/quality/60/format/jpg\",\"detail\":\"http://img.kaiyanapp.com/54680c20ac916565a8cfbee1d4135a2b.png?imageMogr2/quality/60/format/jpg\",\"blurred\":\"http://img.kaiyanapp.com/8690d3989e38acae4d7efe0cbaea59e1.png?imageMogr2/quality/60/format/jpg\",\"sharing\":null,\"homepage\":\"http://img.kaiyanapp.com/54680c20ac916565a8cfbee1d4135a2b.png?imageView2/1/w/720/h/560/format/jpg/q/75|watermark/1/image/aHR0cDovL2ltZy5rYWl5YW5hcHAuY29tL2JsYWNrXzMwLnBuZw==/dissolve/100/gravity/Center/dx/0/dy/0|imageslim\"},\"playUrl\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=112909&resourceType=video&editionType=default&source=aliyun\",\"thumbPlayUrl\":null,\"duration\":109,\"webUrl\":{\"raw\":\"http://www.eyepetizer.net/detail.html?vid=112909\",\"forWeibo\":\"http://www.eyepetizer.net/detail.html?vid=112909\"},\"releaseTime\":1532711225000,\"playInfo\":[{\"height\":480,\"width\":854,\"urlList\":[{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=112909&resourceType=video&editionType=normal&source=aliyun\",\"size\":20044741},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=112909&resourceType=video&editionType=normal&source=qcloud\",\"size\":20044741},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=112909&resourceType=video&editionType=normal&source=ucloud\",\"size\":20044741}],\"name\":\"标清\",\"type\":\"normal\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=112909&resourceType=video&editionType=normal&source=aliyun\"},{\"height\":720,\"width\":1280,\"urlList\":[{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=112909&resourceType=video&editionType=high&source=aliyun\",\"size\":32944056},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=112909&resourceType=video&editionType=high&source=qcloud\",\"size\":32944056},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=112909&resourceType=video&editionType=high&source=ucloud\",\"size\":32944056}],\"name\":\"高清\",\"type\":\"high\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=112909&resourceType=video&editionType=high&source=aliyun\"}],\"campaign\":null,\"waterMarks\":null,\"adTrack\":null,\"type\":\"NORMAL\",\"titlePgc\":null,\"descriptionPgc\":null,\"remark\":null,\"ifLimitVideo\":false,\"searchWeight\":0,\"idx\":0,\"shareAdTrack\":null,\"favoriteAdTrack\":null,\"webAdTrack\":null,\"date\":1534640400000,\"promotion\":null,\"label\":null,\"labelList\":[],\"descriptionEditor\":\"看多了手机上的风光，你会觉得这个世界也就如此，要是离开手机，你会怎么办？有句台词叫「真实自有其力量」，在说这句话的时候，主人公眼神放光，我想他想看的该是没 P 过的世界吧。From Motion Craft\",\"collected\":false,\"played\":false,\"subtitles\":[],\"lastViewTime\":null,\"playlists\":null,\"src\":null},\"tag\":null,\"id\":0,\"adIndex\":-1}]\n         * count : 5\n         */\n\n        private long releaseTime;\n        private String type;\n        private long date;\n        private long publishTime;\n        private int count;\n        private List<ItemList> itemList;\n\n        public long getReleaseTime() {\n            return releaseTime;\n        }\n\n        public void setReleaseTime(long releaseTime) {\n            this.releaseTime = releaseTime;\n        }\n\n        public String getType() {\n            return type;\n        }\n\n        public void setType(String type) {\n            this.type = type;\n        }\n\n        public long getDate() {\n            return date;\n        }\n\n        public void setDate(long date) {\n            this.date = date;\n        }\n\n        public long getPublishTime() {\n            return publishTime;\n        }\n\n        public void setPublishTime(long publishTime) {\n            this.publishTime = publishTime;\n        }\n\n        public int getCount() {\n            return count;\n        }\n\n        public void setCount(int count) {\n            this.count = count;\n        }\n\n        public List<ItemList> getItemList() {\n            return itemList;\n        }\n\n        public void setItemList(List<ItemList> itemList) {\n            this.itemList = itemList;\n        }\n\n        public static class ItemList {\n            /**\n             * type : video\n             * data : {\"dataType\":\"VideoBeanForClient\",\"id\":122208,\"title\":\"致敬经典：当吉卜力动画走进现实\",\"description\":\"本片作者是来自韩国的 Kojer，他将吉卜力工作室耳熟能详的动画人物「放」进了真实的世界中，竟毫无违和感。有「千与千寻」、「龙猫」和「天空之城」等，你最爱的是哪一个场景？From Sunflower12\",\"library\":\"DAILY\",\"tags\":[{\"id\":470,\"name\":\"吉卜力\",\"actionUrl\":\"eyepetizer://tag/470/?title=%E5%90%89%E5%8D%9C%E5%8A%9B\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/2d50274d224680bf06d3062d6874482b.jpeg?imageMogr2/quality/60\",\"headerImage\":\"http://img.kaiyanapp.com/2d50274d224680bf06d3062d6874482b.jpeg?imageMogr2/quality/60\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":570,\"name\":\"电影相关\",\"actionUrl\":\"eyepetizer://tag/570/?title=%E7%94%B5%E5%BD%B1%E7%9B%B8%E5%85%B3\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/bee7c0cd647345f911c10be60ffcde93.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/bee7c0cd647345f911c10be60ffcde93.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":506,\"name\":\"经典\",\"actionUrl\":\"eyepetizer://tag/506/?title=%E7%BB%8F%E5%85%B8\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/1e948eab70737d8beca9f52fce907ab5.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/1e948eab70737d8beca9f52fce907ab5.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":424,\"name\":\"宫崎骏\",\"actionUrl\":\"eyepetizer://tag/424/?title=%E5%AE%AB%E5%B4%8E%E9%AA%8F\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/00f9596704c7eeb7ef65d095b453c8b3.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/00f9596704c7eeb7ef65d095b453c8b3.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":749,\"name\":\"影视周边\",\"actionUrl\":\"eyepetizer://tag/749/?title=%E5%BD%B1%E8%A7%86%E5%91%A8%E8%BE%B9\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/787bc5416e2a985520834eafa9d132af.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/787bc5416e2a985520834eafa9d132af.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null}],\"consumption\":{\"collectionCount\":1000,\"shareCount\":641,\"replyCount\":33},\"resourceType\":\"video\",\"slogan\":\"世界瞬间变成令人感动的童话乐园\",\"provider\":{\"name\":\"YouTube\",\"alias\":\"youtube\",\"icon\":\"http://img.kaiyanapp.com/fa20228bc5b921e837156923a58713f6.png\"},\"category\":\"影视\",\"author\":{\"id\":2173,\"icon\":\"http://img.kaiyanapp.com/003829087e85ce7310b2210d9575ce67.jpeg\",\"name\":\"开眼影视精选\",\"description\":\"关于电影、剧集的一切\",\"link\":\"\",\"latestReleaseTime\":1534640409000,\"videoNum\":442,\"adTrack\":null,\"follow\":{\"itemType\":\"author\",\"itemId\":2173,\"followed\":false},\"shield\":{\"itemType\":\"author\",\"itemId\":2173,\"shielded\":false},\"approvedNotReadyVideoCount\":0,\"ifPgc\":true},\"cover\":{\"feed\":\"http://img.kaiyanapp.com/11f42b2135bb7553b144f5fc7111a56f.jpeg?imageMogr2/quality/60/format/jpg\",\"detail\":\"http://img.kaiyanapp.com/11f42b2135bb7553b144f5fc7111a56f.jpeg?imageMogr2/quality/60/format/jpg\",\"blurred\":\"http://img.kaiyanapp.com/a7399848cb61d7ea2e7707050cc7b243.jpeg?imageMogr2/quality/60/format/jpg\",\"sharing\":null,\"homepage\":\"http://img.kaiyanapp.com/11f42b2135bb7553b144f5fc7111a56f.jpeg?imageView2/1/w/720/h/560/format/jpg/q/75|watermark/1/image/aHR0cDovL2ltZy5rYWl5YW5hcHAuY29tL2JsYWNrXzMwLnBuZw==/dissolve/100/gravity/Center/dx/0/dy/0|imageslim\"},\"playUrl\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=default&source=aliyun\",\"thumbPlayUrl\":null,\"duration\":220,\"webUrl\":{\"raw\":\"http://www.eyepetizer.net/detail.html?vid=122208\",\"forWeibo\":\"http://www.eyepetizer.net/detail.html?vid=122208&resourceType=video&utm_campaign=routine&utm_medium=share&utm_source=weibo&uid=0\"},\"releaseTime\":1534640409000,\"playInfo\":[{\"height\":480,\"width\":854,\"urlList\":[{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=normal&source=aliyun\",\"size\":25152959},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=normal&source=qcloud\",\"size\":25152959},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=normal&source=ucloud\",\"size\":25152959}],\"name\":\"标清\",\"type\":\"normal\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=normal&source=aliyun\"},{\"height\":720,\"width\":1280,\"urlList\":[{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=high&source=aliyun\",\"size\":36837465},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=high&source=qcloud\",\"size\":36837465},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=high&source=ucloud\",\"size\":36837465}],\"name\":\"高清\",\"type\":\"high\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=high&source=aliyun\"}],\"campaign\":null,\"waterMarks\":null,\"adTrack\":null,\"type\":\"NORMAL\",\"titlePgc\":null,\"descriptionPgc\":null,\"remark\":null,\"ifLimitVideo\":false,\"searchWeight\":0,\"idx\":0,\"shareAdTrack\":null,\"favoriteAdTrack\":null,\"webAdTrack\":null,\"date\":1534640400000,\"promotion\":null,\"label\":null,\"labelList\":[],\"descriptionEditor\":\"本片作者是来自韩国的 Kojer，他将吉卜力工作室耳熟能详的动画人物「放」进了真实的世界中，竟毫无违和感。有「千与千寻」、「龙猫」和「天空之城」等，你最爱的是哪一个场景？From Sunflower12\",\"collected\":false,\"played\":false,\"subtitles\":[],\"lastViewTime\":null,\"playlists\":null,\"src\":null}\n             * tag : null\n             * id : 0\n             * adIndex : -1\n             */\n\n            private String type;\n            private Data data;\n            private Object tag;\n            private int id;\n            private int adIndex;\n\n            public String getType() {\n                return type;\n            }\n\n            public void setType(String type) {\n                this.type = type;\n            }\n\n            public Data getData() {\n                return data;\n            }\n\n            public void setData(Data data) {\n                this.data = data;\n            }\n\n            public Object getTag() {\n                return tag;\n            }\n\n            public void setTag(Object tag) {\n                this.tag = tag;\n            }\n\n            public int getId() {\n                return id;\n            }\n\n            public void setId(int id) {\n                this.id = id;\n            }\n\n            public int getAdIndex() {\n                return adIndex;\n            }\n\n            public void setAdIndex(int adIndex) {\n                this.adIndex = adIndex;\n            }\n\n            public static class Data {\n                /**\n                 * dataType : VideoBeanForClient\n                 * id : 122208\n                 * title : 致敬经典：当吉卜力动画走进现实\n                 * description : 本片作者是来自韩国的 Kojer，他将吉卜力工作室耳熟能详的动画人物「放」进了真实的世界中，竟毫无违和感。有「千与千寻」、「龙猫」和「天空之城」等，你最爱的是哪一个场景？From Sunflower12\n                 * library : DAILY\n                 * tags : [{\"id\":470,\"name\":\"吉卜力\",\"actionUrl\":\"eyepetizer://tag/470/?title=%E5%90%89%E5%8D%9C%E5%8A%9B\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/2d50274d224680bf06d3062d6874482b.jpeg?imageMogr2/quality/60\",\"headerImage\":\"http://img.kaiyanapp.com/2d50274d224680bf06d3062d6874482b.jpeg?imageMogr2/quality/60\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":570,\"name\":\"电影相关\",\"actionUrl\":\"eyepetizer://tag/570/?title=%E7%94%B5%E5%BD%B1%E7%9B%B8%E5%85%B3\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/bee7c0cd647345f911c10be60ffcde93.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/bee7c0cd647345f911c10be60ffcde93.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":506,\"name\":\"经典\",\"actionUrl\":\"eyepetizer://tag/506/?title=%E7%BB%8F%E5%85%B8\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/1e948eab70737d8beca9f52fce907ab5.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/1e948eab70737d8beca9f52fce907ab5.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":424,\"name\":\"宫崎骏\",\"actionUrl\":\"eyepetizer://tag/424/?title=%E5%AE%AB%E5%B4%8E%E9%AA%8F\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/00f9596704c7eeb7ef65d095b453c8b3.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/00f9596704c7eeb7ef65d095b453c8b3.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null},{\"id\":749,\"name\":\"影视周边\",\"actionUrl\":\"eyepetizer://tag/749/?title=%E5%BD%B1%E8%A7%86%E5%91%A8%E8%BE%B9\",\"adTrack\":null,\"desc\":null,\"bgPicture\":\"http://img.kaiyanapp.com/787bc5416e2a985520834eafa9d132af.jpeg?imageMogr2/quality/60/format/jpg\",\"headerImage\":\"http://img.kaiyanapp.com/787bc5416e2a985520834eafa9d132af.jpeg?imageMogr2/quality/60/format/jpg\",\"tagRecType\":\"NORMAL\",\"childTagList\":null,\"childTagIdList\":null}]\n                 * consumption : {\"collectionCount\":1000,\"shareCount\":641,\"replyCount\":33}\n                 * resourceType : video\n                 * slogan : 世界瞬间变成令人感动的童话乐园\n                 * provider : {\"name\":\"YouTube\",\"alias\":\"youtube\",\"icon\":\"http://img.kaiyanapp.com/fa20228bc5b921e837156923a58713f6.png\"}\n                 * category : 影视\n                 * author : {\"id\":2173,\"icon\":\"http://img.kaiyanapp.com/003829087e85ce7310b2210d9575ce67.jpeg\",\"name\":\"开眼影视精选\",\"description\":\"关于电影、剧集的一切\",\"link\":\"\",\"latestReleaseTime\":1534640409000,\"videoNum\":442,\"adTrack\":null,\"follow\":{\"itemType\":\"author\",\"itemId\":2173,\"followed\":false},\"shield\":{\"itemType\":\"author\",\"itemId\":2173,\"shielded\":false},\"approvedNotReadyVideoCount\":0,\"ifPgc\":true}\n                 * cover : {\"feed\":\"http://img.kaiyanapp.com/11f42b2135bb7553b144f5fc7111a56f.jpeg?imageMogr2/quality/60/format/jpg\",\"detail\":\"http://img.kaiyanapp.com/11f42b2135bb7553b144f5fc7111a56f.jpeg?imageMogr2/quality/60/format/jpg\",\"blurred\":\"http://img.kaiyanapp.com/a7399848cb61d7ea2e7707050cc7b243.jpeg?imageMogr2/quality/60/format/jpg\",\"sharing\":null,\"homepage\":\"http://img.kaiyanapp.com/11f42b2135bb7553b144f5fc7111a56f.jpeg?imageView2/1/w/720/h/560/format/jpg/q/75|watermark/1/image/aHR0cDovL2ltZy5rYWl5YW5hcHAuY29tL2JsYWNrXzMwLnBuZw==/dissolve/100/gravity/Center/dx/0/dy/0|imageslim\"}\n                 * playUrl : http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=default&source=aliyun\n                 * thumbPlayUrl : null\n                 * duration : 220\n                 * webUrl : {\"raw\":\"http://www.eyepetizer.net/detail.html?vid=122208\",\"forWeibo\":\"http://www.eyepetizer.net/detail.html?vid=122208&resourceType=video&utm_campaign=routine&utm_medium=share&utm_source=weibo&uid=0\"}\n                 * releaseTime : 1534640409000\n                 * playInfo : [{\"height\":480,\"width\":854,\"urlList\":[{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=normal&source=aliyun\",\"size\":25152959},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=normal&source=qcloud\",\"size\":25152959},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=normal&source=ucloud\",\"size\":25152959}],\"name\":\"标清\",\"type\":\"normal\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=normal&source=aliyun\"},{\"height\":720,\"width\":1280,\"urlList\":[{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=high&source=aliyun\",\"size\":36837465},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=high&source=qcloud\",\"size\":36837465},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=high&source=ucloud\",\"size\":36837465}],\"name\":\"高清\",\"type\":\"high\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=high&source=aliyun\"}]\n                 * campaign : null\n                 * waterMarks : null\n                 * adTrack : null\n                 * type : NORMAL\n                 * titlePgc : null\n                 * descriptionPgc : null\n                 * remark : null\n                 * ifLimitVideo : false\n                 * searchWeight : 0\n                 * idx : 0\n                 * shareAdTrack : null\n                 * favoriteAdTrack : null\n                 * webAdTrack : null\n                 * date : 1534640400000\n                 * promotion : null\n                 * label : null\n                 * labelList : []\n                 * descriptionEditor : 本片作者是来自韩国的 Kojer，他将吉卜力工作室耳熟能详的动画人物「放」进了真实的世界中，竟毫无违和感。有「千与千寻」、「龙猫」和「天空之城」等，你最爱的是哪一个场景？From Sunflower12\n                 * collected : false\n                 * played : false\n                 * subtitles : []\n                 * lastViewTime : null\n                 * playlists : null\n                 * src : null\n                 */\n\n                private String dataType;\n                private int id;\n                private String title;\n                private String description;\n                private String library;\n                private Consumption consumption;\n                private String resourceType;\n                private String slogan;\n                private Provider provider;\n                private String category;\n                private Author author;\n                private Cover cover;\n                private String playUrl;\n                private Object thumbPlayUrl;\n                private int duration;\n                private WebUrl webUrl;\n                private long releaseTime;\n                private Object campaign;\n                private Object waterMarks;\n                private Object adTrack;\n                private String type;\n                private Object titlePgc;\n                private Object descriptionPgc;\n                private Object remark;\n                private boolean ifLimitVideo;\n                private int searchWeight;\n                private int idx;\n                private Object shareAdTrack;\n                private Object favoriteAdTrack;\n                private Object webAdTrack;\n                private long date;\n                private Object promotion;\n                private Object label;\n                private String descriptionEditor;\n                private boolean collected;\n                private boolean played;\n                private Object lastViewTime;\n                private Object playlists;\n                private Object src;\n                private List<Tags> tags;\n                private List<PlayInfo> playInfo;\n                private List<?> labelList;\n                private List<?> subtitles;\n\n                public String getDataType() {\n                    return dataType;\n                }\n\n                public void setDataType(String dataType) {\n                    this.dataType = dataType;\n                }\n\n                public int getId() {\n                    return id;\n                }\n\n                public void setId(int id) {\n                    this.id = id;\n                }\n\n                public String getTitle() {\n                    return title;\n                }\n\n                public void setTitle(String title) {\n                    this.title = title;\n                }\n\n                public String getDescription() {\n                    return description;\n                }\n\n                public void setDescription(String description) {\n                    this.description = description;\n                }\n\n                public String getLibrary() {\n                    return library;\n                }\n\n                public void setLibrary(String library) {\n                    this.library = library;\n                }\n\n                public Consumption getConsumption() {\n                    return consumption;\n                }\n\n                public void setConsumption(Consumption consumption) {\n                    this.consumption = consumption;\n                }\n\n                public String getResourceType() {\n                    return resourceType;\n                }\n\n                public void setResourceType(String resourceType) {\n                    this.resourceType = resourceType;\n                }\n\n                public String getSlogan() {\n                    return slogan;\n                }\n\n                public void setSlogan(String slogan) {\n                    this.slogan = slogan;\n                }\n\n                public Provider getProvider() {\n                    return provider;\n                }\n\n                public void setProvider(Provider provider) {\n                    this.provider = provider;\n                }\n\n                public String getCategory() {\n                    return category;\n                }\n\n                public void setCategory(String category) {\n                    this.category = category;\n                }\n\n                public Author getAuthor() {\n                    return author;\n                }\n\n                public void setAuthor(Author author) {\n                    this.author = author;\n                }\n\n                public Cover getCover() {\n                    return cover;\n                }\n\n                public void setCover(Cover cover) {\n                    this.cover = cover;\n                }\n\n                public String getPlayUrl() {\n                    return playUrl;\n                }\n\n                public void setPlayUrl(String playUrl) {\n                    this.playUrl = playUrl;\n                }\n\n                public Object getThumbPlayUrl() {\n                    return thumbPlayUrl;\n                }\n\n                public void setThumbPlayUrl(Object thumbPlayUrl) {\n                    this.thumbPlayUrl = thumbPlayUrl;\n                }\n\n                public int getDuration() {\n                    return duration;\n                }\n\n                public void setDuration(int duration) {\n                    this.duration = duration;\n                }\n\n                public WebUrl getWebUrl() {\n                    return webUrl;\n                }\n\n                public void setWebUrl(WebUrl webUrl) {\n                    this.webUrl = webUrl;\n                }\n\n                public long getReleaseTime() {\n                    return releaseTime;\n                }\n\n                public void setReleaseTime(long releaseTime) {\n                    this.releaseTime = releaseTime;\n                }\n\n                public Object getCampaign() {\n                    return campaign;\n                }\n\n                public void setCampaign(Object campaign) {\n                    this.campaign = campaign;\n                }\n\n                public Object getWaterMarks() {\n                    return waterMarks;\n                }\n\n                public void setWaterMarks(Object waterMarks) {\n                    this.waterMarks = waterMarks;\n                }\n\n                public Object getAdTrack() {\n                    return adTrack;\n                }\n\n                public void setAdTrack(Object adTrack) {\n                    this.adTrack = adTrack;\n                }\n\n                public String getType() {\n                    return type;\n                }\n\n                public void setType(String type) {\n                    this.type = type;\n                }\n\n                public Object getTitlePgc() {\n                    return titlePgc;\n                }\n\n                public void setTitlePgc(Object titlePgc) {\n                    this.titlePgc = titlePgc;\n                }\n\n                public Object getDescriptionPgc() {\n                    return descriptionPgc;\n                }\n\n                public void setDescriptionPgc(Object descriptionPgc) {\n                    this.descriptionPgc = descriptionPgc;\n                }\n\n                public Object getRemark() {\n                    return remark;\n                }\n\n                public void setRemark(Object remark) {\n                    this.remark = remark;\n                }\n\n                public boolean isIfLimitVideo() {\n                    return ifLimitVideo;\n                }\n\n                public void setIfLimitVideo(boolean ifLimitVideo) {\n                    this.ifLimitVideo = ifLimitVideo;\n                }\n\n                public int getSearchWeight() {\n                    return searchWeight;\n                }\n\n                public void setSearchWeight(int searchWeight) {\n                    this.searchWeight = searchWeight;\n                }\n\n                public int getIdx() {\n                    return idx;\n                }\n\n                public void setIdx(int idx) {\n                    this.idx = idx;\n                }\n\n                public Object getShareAdTrack() {\n                    return shareAdTrack;\n                }\n\n                public void setShareAdTrack(Object shareAdTrack) {\n                    this.shareAdTrack = shareAdTrack;\n                }\n\n                public Object getFavoriteAdTrack() {\n                    return favoriteAdTrack;\n                }\n\n                public void setFavoriteAdTrack(Object favoriteAdTrack) {\n                    this.favoriteAdTrack = favoriteAdTrack;\n                }\n\n                public Object getWebAdTrack() {\n                    return webAdTrack;\n                }\n\n                public void setWebAdTrack(Object webAdTrack) {\n                    this.webAdTrack = webAdTrack;\n                }\n\n                public long getDate() {\n                    return date;\n                }\n\n                public void setDate(long date) {\n                    this.date = date;\n                }\n\n                public Object getPromotion() {\n                    return promotion;\n                }\n\n                public void setPromotion(Object promotion) {\n                    this.promotion = promotion;\n                }\n\n                public Object getLabel() {\n                    return label;\n                }\n\n                public void setLabel(Object label) {\n                    this.label = label;\n                }\n\n                public String getDescriptionEditor() {\n                    return descriptionEditor;\n                }\n\n                public void setDescriptionEditor(String descriptionEditor) {\n                    this.descriptionEditor = descriptionEditor;\n                }\n\n                public boolean isCollected() {\n                    return collected;\n                }\n\n                public void setCollected(boolean collected) {\n                    this.collected = collected;\n                }\n\n                public boolean isPlayed() {\n                    return played;\n                }\n\n                public void setPlayed(boolean played) {\n                    this.played = played;\n                }\n\n                public Object getLastViewTime() {\n                    return lastViewTime;\n                }\n\n                public void setLastViewTime(Object lastViewTime) {\n                    this.lastViewTime = lastViewTime;\n                }\n\n                public Object getPlaylists() {\n                    return playlists;\n                }\n\n                public void setPlaylists(Object playlists) {\n                    this.playlists = playlists;\n                }\n\n                public Object getSrc() {\n                    return src;\n                }\n\n                public void setSrc(Object src) {\n                    this.src = src;\n                }\n\n                public List<Tags> getTags() {\n                    return tags;\n                }\n\n                public void setTags(List<Tags> tags) {\n                    this.tags = tags;\n                }\n\n                public List<PlayInfo> getPlayInfo() {\n                    return playInfo;\n                }\n\n                public void setPlayInfo(List<PlayInfo> playInfo) {\n                    this.playInfo = playInfo;\n                }\n\n                public List<?> getLabelList() {\n                    return labelList;\n                }\n\n                public void setLabelList(List<?> labelList) {\n                    this.labelList = labelList;\n                }\n\n                public List<?> getSubtitles() {\n                    return subtitles;\n                }\n\n                public void setSubtitles(List<?> subtitles) {\n                    this.subtitles = subtitles;\n                }\n\n                public static class Consumption {\n                    /**\n                     * collectionCount : 1000\n                     * shareCount : 641\n                     * replyCount : 33\n                     */\n\n                    private int collectionCount;\n                    private int shareCount;\n                    private int replyCount;\n\n                    public int getCollectionCount() {\n                        return collectionCount;\n                    }\n\n                    public void setCollectionCount(int collectionCount) {\n                        this.collectionCount = collectionCount;\n                    }\n\n                    public int getShareCount() {\n                        return shareCount;\n                    }\n\n                    public void setShareCount(int shareCount) {\n                        this.shareCount = shareCount;\n                    }\n\n                    public int getReplyCount() {\n                        return replyCount;\n                    }\n\n                    public void setReplyCount(int replyCount) {\n                        this.replyCount = replyCount;\n                    }\n                }\n\n                public static class Provider {\n                    /**\n                     * name : YouTube\n                     * alias : youtube\n                     * icon : http://img.kaiyanapp.com/fa20228bc5b921e837156923a58713f6.png\n                     */\n\n                    private String name;\n                    private String alias;\n                    private String icon;\n\n                    public String getName() {\n                        return name;\n                    }\n\n                    public void setName(String name) {\n                        this.name = name;\n                    }\n\n                    public String getAlias() {\n                        return alias;\n                    }\n\n                    public void setAlias(String alias) {\n                        this.alias = alias;\n                    }\n\n                    public String getIcon() {\n                        return icon;\n                    }\n\n                    public void setIcon(String icon) {\n                        this.icon = icon;\n                    }\n                }\n\n                public static class Author {\n                    /**\n                     * id : 2173\n                     * icon : http://img.kaiyanapp.com/003829087e85ce7310b2210d9575ce67.jpeg\n                     * name : 开眼影视精选\n                     * description : 关于电影、剧集的一切\n                     * link :\n                     * latestReleaseTime : 1534640409000\n                     * videoNum : 442\n                     * adTrack : null\n                     * follow : {\"itemType\":\"author\",\"itemId\":2173,\"followed\":false}\n                     * shield : {\"itemType\":\"author\",\"itemId\":2173,\"shielded\":false}\n                     * approvedNotReadyVideoCount : 0\n                     * ifPgc : true\n                     */\n\n                    private int id;\n                    private String icon;\n                    private String name;\n                    private String description;\n                    private String link;\n                    private long latestReleaseTime;\n                    private int videoNum;\n                    private Object adTrack;\n                    private Follow follow;\n                    private Shield shield;\n                    private int approvedNotReadyVideoCount;\n                    private boolean ifPgc;\n\n                    public int getId() {\n                        return id;\n                    }\n\n                    public void setId(int id) {\n                        this.id = id;\n                    }\n\n                    public String getIcon() {\n                        return icon;\n                    }\n\n                    public void setIcon(String icon) {\n                        this.icon = icon;\n                    }\n\n                    public String getName() {\n                        return name;\n                    }\n\n                    public void setName(String name) {\n                        this.name = name;\n                    }\n\n                    public String getDescription() {\n                        return description;\n                    }\n\n                    public void setDescription(String description) {\n                        this.description = description;\n                    }\n\n                    public String getLink() {\n                        return link;\n                    }\n\n                    public void setLink(String link) {\n                        this.link = link;\n                    }\n\n                    public long getLatestReleaseTime() {\n                        return latestReleaseTime;\n                    }\n\n                    public void setLatestReleaseTime(long latestReleaseTime) {\n                        this.latestReleaseTime = latestReleaseTime;\n                    }\n\n                    public int getVideoNum() {\n                        return videoNum;\n                    }\n\n                    public void setVideoNum(int videoNum) {\n                        this.videoNum = videoNum;\n                    }\n\n                    public Object getAdTrack() {\n                        return adTrack;\n                    }\n\n                    public void setAdTrack(Object adTrack) {\n                        this.adTrack = adTrack;\n                    }\n\n                    public Follow getFollow() {\n                        return follow;\n                    }\n\n                    public void setFollow(Follow follow) {\n                        this.follow = follow;\n                    }\n\n                    public Shield getShield() {\n                        return shield;\n                    }\n\n                    public void setShield(Shield shield) {\n                        this.shield = shield;\n                    }\n\n                    public int getApprovedNotReadyVideoCount() {\n                        return approvedNotReadyVideoCount;\n                    }\n\n                    public void setApprovedNotReadyVideoCount(int approvedNotReadyVideoCount) {\n                        this.approvedNotReadyVideoCount = approvedNotReadyVideoCount;\n                    }\n\n                    public boolean isIfPgc() {\n                        return ifPgc;\n                    }\n\n                    public void setIfPgc(boolean ifPgc) {\n                        this.ifPgc = ifPgc;\n                    }\n\n                    public static class Follow {\n                        /**\n                         * itemType : author\n                         * itemId : 2173\n                         * followed : false\n                         */\n\n                        private String itemType;\n                        private int itemId;\n                        private boolean followed;\n\n                        public String getItemType() {\n                            return itemType;\n                        }\n\n                        public void setItemType(String itemType) {\n                            this.itemType = itemType;\n                        }\n\n                        public int getItemId() {\n                            return itemId;\n                        }\n\n                        public void setItemId(int itemId) {\n                            this.itemId = itemId;\n                        }\n\n                        public boolean isFollowed() {\n                            return followed;\n                        }\n\n                        public void setFollowed(boolean followed) {\n                            this.followed = followed;\n                        }\n                    }\n\n                    public static class Shield {\n                        /**\n                         * itemType : author\n                         * itemId : 2173\n                         * shielded : false\n                         */\n\n                        private String itemType;\n                        private int itemId;\n                        private boolean shielded;\n\n                        public String getItemType() {\n                            return itemType;\n                        }\n\n                        public void setItemType(String itemType) {\n                            this.itemType = itemType;\n                        }\n\n                        public int getItemId() {\n                            return itemId;\n                        }\n\n                        public void setItemId(int itemId) {\n                            this.itemId = itemId;\n                        }\n\n                        public boolean isShielded() {\n                            return shielded;\n                        }\n\n                        public void setShielded(boolean shielded) {\n                            this.shielded = shielded;\n                        }\n                    }\n                }\n\n                public static class Cover {\n                    /**\n                     * feed : http://img.kaiyanapp.com/11f42b2135bb7553b144f5fc7111a56f.jpeg?imageMogr2/quality/60/format/jpg\n                     * detail : http://img.kaiyanapp.com/11f42b2135bb7553b144f5fc7111a56f.jpeg?imageMogr2/quality/60/format/jpg\n                     * blurred : http://img.kaiyanapp.com/a7399848cb61d7ea2e7707050cc7b243.jpeg?imageMogr2/quality/60/format/jpg\n                     * sharing : null\n                     * homepage : http://img.kaiyanapp.com/11f42b2135bb7553b144f5fc7111a56f.jpeg?imageView2/1/w/720/h/560/format/jpg/q/75|watermark/1/image/aHR0cDovL2ltZy5rYWl5YW5hcHAuY29tL2JsYWNrXzMwLnBuZw==/dissolve/100/gravity/Center/dx/0/dy/0|imageslim\n                     */\n\n                    private String feed;\n                    private String detail;\n                    private String blurred;\n                    private Object sharing;\n                    private String homepage;\n\n                    public String getFeed() {\n                        return feed;\n                    }\n\n                    public void setFeed(String feed) {\n                        this.feed = feed;\n                    }\n\n                    public String getDetail() {\n                        return detail;\n                    }\n\n                    public void setDetail(String detail) {\n                        this.detail = detail;\n                    }\n\n                    public String getBlurred() {\n                        return blurred;\n                    }\n\n                    public void setBlurred(String blurred) {\n                        this.blurred = blurred;\n                    }\n\n                    public Object getSharing() {\n                        return sharing;\n                    }\n\n                    public void setSharing(Object sharing) {\n                        this.sharing = sharing;\n                    }\n\n                    public String getHomepage() {\n                        return homepage;\n                    }\n\n                    public void setHomepage(String homepage) {\n                        this.homepage = homepage;\n                    }\n                }\n\n                public static class WebUrl {\n                    /**\n                     * raw : http://www.eyepetizer.net/detail.html?vid=122208\n                     * forWeibo : http://www.eyepetizer.net/detail.html?vid=122208&resourceType=video&utm_campaign=routine&utm_medium=share&utm_source=weibo&uid=0\n                     */\n\n                    private String raw;\n                    private String forWeibo;\n\n                    public String getRaw() {\n                        return raw;\n                    }\n\n                    public void setRaw(String raw) {\n                        this.raw = raw;\n                    }\n\n                    public String getForWeibo() {\n                        return forWeibo;\n                    }\n\n                    public void setForWeibo(String forWeibo) {\n                        this.forWeibo = forWeibo;\n                    }\n                }\n\n                public static class Tags {\n                    /**\n                     * id : 470\n                     * name : 吉卜力\n                     * actionUrl : eyepetizer://tag/470/?title=%E5%90%89%E5%8D%9C%E5%8A%9B\n                     * adTrack : null\n                     * desc : null\n                     * bgPicture : http://img.kaiyanapp.com/2d50274d224680bf06d3062d6874482b.jpeg?imageMogr2/quality/60\n                     * headerImage : http://img.kaiyanapp.com/2d50274d224680bf06d3062d6874482b.jpeg?imageMogr2/quality/60\n                     * tagRecType : NORMAL\n                     * childTagList : null\n                     * childTagIdList : null\n                     */\n\n                    private int id;\n                    private String name;\n                    private String actionUrl;\n                    private Object adTrack;\n                    private Object desc;\n                    private String bgPicture;\n                    private String headerImage;\n                    private String tagRecType;\n                    private Object childTagList;\n                    private Object childTagIdList;\n\n                    public int getId() {\n                        return id;\n                    }\n\n                    public void setId(int id) {\n                        this.id = id;\n                    }\n\n                    public String getName() {\n                        return name;\n                    }\n\n                    public void setName(String name) {\n                        this.name = name;\n                    }\n\n                    public String getActionUrl() {\n                        return actionUrl;\n                    }\n\n                    public void setActionUrl(String actionUrl) {\n                        this.actionUrl = actionUrl;\n                    }\n\n                    public Object getAdTrack() {\n                        return adTrack;\n                    }\n\n                    public void setAdTrack(Object adTrack) {\n                        this.adTrack = adTrack;\n                    }\n\n                    public Object getDesc() {\n                        return desc;\n                    }\n\n                    public void setDesc(Object desc) {\n                        this.desc = desc;\n                    }\n\n                    public String getBgPicture() {\n                        return bgPicture;\n                    }\n\n                    public void setBgPicture(String bgPicture) {\n                        this.bgPicture = bgPicture;\n                    }\n\n                    public String getHeaderImage() {\n                        return headerImage;\n                    }\n\n                    public void setHeaderImage(String headerImage) {\n                        this.headerImage = headerImage;\n                    }\n\n                    public String getTagRecType() {\n                        return tagRecType;\n                    }\n\n                    public void setTagRecType(String tagRecType) {\n                        this.tagRecType = tagRecType;\n                    }\n\n                    public Object getChildTagList() {\n                        return childTagList;\n                    }\n\n                    public void setChildTagList(Object childTagList) {\n                        this.childTagList = childTagList;\n                    }\n\n                    public Object getChildTagIdList() {\n                        return childTagIdList;\n                    }\n\n                    public void setChildTagIdList(Object childTagIdList) {\n                        this.childTagIdList = childTagIdList;\n                    }\n                }\n\n                public static class PlayInfo {\n                    /**\n                     * height : 480\n                     * width : 854\n                     * urlList : [{\"name\":\"aliyun\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=normal&source=aliyun\",\"size\":25152959},{\"name\":\"qcloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=normal&source=qcloud\",\"size\":25152959},{\"name\":\"ucloud\",\"url\":\"http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=normal&source=ucloud\",\"size\":25152959}]\n                     * name : 标清\n                     * type : normal\n                     * url : http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=normal&source=aliyun\n                     */\n\n                    private int height;\n                    private int width;\n                    private String name;\n                    private String type;\n                    private String url;\n                    private List<UrlList> urlList;\n\n                    public int getHeight() {\n                        return height;\n                    }\n\n                    public void setHeight(int height) {\n                        this.height = height;\n                    }\n\n                    public int getWidth() {\n                        return width;\n                    }\n\n                    public void setWidth(int width) {\n                        this.width = width;\n                    }\n\n                    public String getName() {\n                        return name;\n                    }\n\n                    public void setName(String name) {\n                        this.name = name;\n                    }\n\n                    public String getType() {\n                        return type;\n                    }\n\n                    public void setType(String type) {\n                        this.type = type;\n                    }\n\n                    public String getUrl() {\n                        return url;\n                    }\n\n                    public void setUrl(String url) {\n                        this.url = url;\n                    }\n\n                    public List<UrlList> getUrlList() {\n                        return urlList;\n                    }\n\n                    public void setUrlList(List<UrlList> urlList) {\n                        this.urlList = urlList;\n                    }\n\n                    public static class UrlList {\n                        /**\n                         * name : aliyun\n                         * url : http://baobab.kaiyanapp.com/api/v1/playUrl?vid=122208&resourceType=video&editionType=normal&source=aliyun\n                         * size : 25152959\n                         */\n\n                        private String name;\n                        private String url;\n                        private int size;\n\n                        public String getName() {\n                            return name;\n                        }\n\n                        public void setName(String name) {\n                            this.name = name;\n                        }\n\n                        public String getUrl() {\n                            return url;\n                        }\n\n                        public void setUrl(String url) {\n                            this.url = url;\n                        }\n\n                        public int getSize() {\n                            return size;\n                        }\n\n                        public void setSize(int size) {\n                            this.size = size;\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "eyepetizer/src/main/java/me/shouheng/eyepetizer/mvp/presenter/HomePresenter.java",
    "content": "package me.shouheng.eyepetizer.mvp.presenter;\n\nimport java.util.LinkedList;\nimport java.util.List;\n\nimport io.reactivex.Observable;\nimport io.reactivex.ObservableSource;\nimport io.reactivex.android.schedulers.AndroidSchedulers;\nimport io.reactivex.disposables.Disposable;\nimport io.reactivex.functions.Function;\nimport io.reactivex.schedulers.Schedulers;\nimport me.shouheng.commons.tools.LogUtils;\nimport me.shouheng.eyepetizer.mvp.contract.HomeContract;\nimport me.shouheng.eyepetizer.mvp.model.HomeModel;\nimport me.shouheng.eyepetizer.mvp.model.bean.HomeBean;\n\n/**\n * @author shouh\n * @version $Id: HomePresenter, v 0.1 2018/8/19 17:39 shouh Exp$\n */\npublic class HomePresenter implements HomeContract.IPresenter {\n\n    private HomeContract.IView view;\n\n    private HomeModel homeModel;\n\n    private String nextPageUrl;\n\n    public HomePresenter(HomeContract.IView view) {\n        this.view = view;\n        homeModel = new HomeModel();\n    }\n\n    @Override\n    public void requestFirstPage() {\n        Disposable disposable = homeModel.getFirstHomeData()\n                .subscribeOn(Schedulers.io())\n                .observeOn(AndroidSchedulers.mainThread())\n                .map(homeBean -> {\n                    List<HomeBean.IssueList> issueLists = homeBean.getIssueList();\n                    nextPageUrl = homeBean.getNextPageUrl();\n                    return issueLists.get(0).getItemList();\n                })\n                .subscribe(itemLists -> {\n                            List<HomeBean.IssueList.ItemList> ret = new LinkedList<>();\n                            Observable.fromIterable(itemLists)\n                                    .filter(itemList -> \"video\".equals(itemList.getType()))\n                                    .forEach(ret::add);\n                            view.setFirstPage(ret);\n                        },\n                        throwable -> {\n                            view.onError(throwable.toString());\n                            LogUtils.d(throwable);\n                        });\n    }\n\n    @Override\n    public void requestNextPage() {\n        Disposable disposable = homeModel.getMoreHomeData(nextPageUrl)\n                .subscribeOn(Schedulers.io())\n                .observeOn(AndroidSchedulers.mainThread())\n                .map(homeBean -> {\n                    nextPageUrl = homeBean.getNextPageUrl();\n                    return homeBean.getIssueList();\n                })\n                .concatMap((Function<List<HomeBean.IssueList>, ObservableSource<List<HomeBean.IssueList.ItemList>>>) issueLists ->\n                        Observable.fromIterable(issueLists).concatMap((Function<HomeBean.IssueList, ObservableSource<List<HomeBean.IssueList.ItemList>>>) issueList ->\n                                Observable.just(issueList.getItemList())))\n                .subscribe(itemLists -> {\n                            List<HomeBean.IssueList.ItemList> ret = new LinkedList<>();\n                            Observable.fromIterable(itemLists)\n                                    .filter(itemList -> \"video\".equals(itemList.getType()))\n                                    .forEach(ret::add);\n                            view.setFirstPage(ret);\n                        },\n                        throwable -> {\n                            view.onError(throwable.toString());\n                            LogUtils.d(throwable);\n                        });\n    }\n}\n"
  },
  {
    "path": "eyepetizer/src/main/java/me/shouheng/eyepetizer/net/APIRetrofit.java",
    "content": "package me.shouheng.eyepetizer.net;\n\nimport java.util.concurrent.TimeUnit;\n\nimport okhttp3.OkHttpClient;\nimport retrofit2.Retrofit;\nimport retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;\nimport retrofit2.converter.gson.GsonConverterFactory;\n\n/**\n * @author shouh\n * @version $Id: APIRetrofit, v 0.1 2018/8/19 17:29 shouh Exp$\n */\npublic class APIRetrofit {\n\n    public static APIService getEyepetizerService() {\n        return new Retrofit.Builder()\n                .baseUrl(\"http://baobab.kaiyanapp.com/api/\")\n                .addConverterFactory(GsonConverterFactory.create())\n                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())\n                .client(getOkHttpClient())\n                .build().create(APIService.class);\n    }\n\n    private static OkHttpClient getOkHttpClient() {\n        return new OkHttpClient.Builder()\n                .connectTimeout(10, TimeUnit.SECONDS)\n                .readTimeout(10, TimeUnit.SECONDS)\n                .writeTimeout(10, TimeUnit.SECONDS)\n                .build();\n    }\n}\n"
  },
  {
    "path": "eyepetizer/src/main/java/me/shouheng/eyepetizer/net/APIService.java",
    "content": "package me.shouheng.eyepetizer.net;\n\nimport io.reactivex.Observable;\nimport me.shouheng.eyepetizer.mvp.model.bean.HomeBean;\nimport retrofit2.http.GET;\nimport retrofit2.http.Query;\nimport retrofit2.http.Url;\n\n/**\n * @author shouh\n * @version $Id: APIService, v 0.1 2018/8/19 17:30 shouh Exp$\n */\npublic interface APIService {\n\n    @GET(\"v2/feed?&num=1\")\n    Observable<HomeBean> getFirstHomeData(@Query(\"date\") Long date);\n\n    @GET\n    Observable<HomeBean> getMoreHomeData(@Url String url);\n}\n"
  },
  {
    "path": "eyepetizer/src/main/java/me/shouheng/eyepetizer/ui/activity/ContainerActivity.java",
    "content": "package me.shouheng.eyepetizer.ui.activity;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport androidx.fragment.app.Fragment;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.alibaba.android.arouter.launcher.ARouter;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.FragmentHelper;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.eyepetizer.R;\nimport me.shouheng.eyepetizer.databinding.ActivityContainerBinding;\n\n@Route(path = BaseConstants.EYEPETIZER_CONTAINER)\npublic class ContainerActivity extends CommonActivity<ActivityContainerBinding> {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_container;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        Intent intent = getIntent();\n        String url = intent.getStringExtra(BaseConstants.EYEPETIZER_CONTAINER_ACTION_VIDEO_EXTRA_URL);\n        Fragment fragment = (Fragment) ARouter.getInstance()\n                .build(BaseConstants.EYEPETIZER_VIDEO)\n                .withString(BaseConstants.EYEPETIZER_VIDEO_EXTRA_URL, url)\n                .withBoolean(BaseConstants.EYEPETIZER_VIDEO_EXTRA_FULLSCREEN, true)\n                .navigation();\n        FragmentHelper.replace(this, fragment, R.id.fragment_container);\n    }\n}\n"
  },
  {
    "path": "eyepetizer/src/main/java/me/shouheng/eyepetizer/ui/activity/HomeActivity.java",
    "content": "package me.shouheng.eyepetizer.ui.activity;\n\nimport android.os.Bundle;\nimport androidx.appcompat.app.ActionBar;\nimport androidx.recyclerview.widget.LinearLayoutManager;\nimport androidx.recyclerview.widget.RecyclerView;\nimport androidx.appcompat.widget.Toolbar;\nimport android.view.MenuItem;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.alibaba.android.arouter.launcher.ARouter;\n\nimport java.util.List;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.ToastUtils;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.commons.view.widget.DividerItemDecoration;\nimport me.shouheng.eyepetizer.R;\nimport me.shouheng.eyepetizer.databinding.ActivityEyepetizerMenuBinding;\nimport me.shouheng.eyepetizer.mvp.contract.HomeContract;\nimport me.shouheng.eyepetizer.mvp.model.bean.HomeBean;\nimport me.shouheng.eyepetizer.mvp.presenter.HomePresenter;\nimport me.shouheng.eyepetizer.ui.adapter.HomeAdapter;\n\n@Route(path = BaseConstants.EYEPETIZER_MENU)\npublic class HomeActivity extends CommonActivity<ActivityEyepetizerMenuBinding> implements HomeContract.IView {\n\n    private HomeAdapter homeAdapter;\n\n    private boolean loading = false;\n\n    private HomeContract.IPresenter presenter;\n\n    {\n        presenter = new HomePresenter(this);\n    }\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_eyepetizer_menu;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n\n        configToolbar();\n\n        configList();\n\n        presenter.requestFirstPage();\n        loading = true;\n    }\n\n    private void configToolbar() {\n        Toolbar toolbar = getBinding().barLayout.toolbar;\n        toolbar.setBackgroundResource(R.color.light_theme_background);\n        setSupportActionBar(toolbar);\n        ActionBar actionBar = getSupportActionBar();\n        if (actionBar != null) {\n            actionBar.setTitle(R.string.menu_item_title_5);\n            actionBar.setSubtitle(R.string.menu_item_desc_5);\n            actionBar.setDisplayHomeAsUpEnabled(true);\n        }\n    }\n\n    private void configList() {\n        homeAdapter = new HomeAdapter(getContext());\n        homeAdapter.setOnItemClickListener(((adapter1, view, position) -> {\n            HomeBean.IssueList.ItemList itemList = homeAdapter.getData().get(position);\n            ARouter.getInstance()\n                    .build(BaseConstants.EYEPETIZER_CONTAINER)\n                    .withString(BaseConstants.EYEPETIZER_CONTAINER_ACTION_VIDEO_EXTRA_URL, itemList.getData().getPlayUrl())\n                    .navigation();\n        }));\n\n        getBinding().rv.setAdapter(homeAdapter);\n        getBinding().rv.addItemDecoration(new DividerItemDecoration(getContext(),\n                DividerItemDecoration.VERTICAL_LIST, false));\n        LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());\n        getBinding().rv.setLayoutManager(layoutManager);\n\n        getBinding().rv.addOnScrollListener(new RecyclerView.OnScrollListener() {\n            @Override\n            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {\n                super.onScrolled(recyclerView, dx, dy);\n                int lastVisibleItem = layoutManager.findLastVisibleItemPosition();\n                int totalItemCount = layoutManager.getItemCount();\n                if (lastVisibleItem + 1 == totalItemCount && dy > 0) {\n                    if (!loading) {\n                        loading = true;\n                        presenter.requestNextPage();\n                    }\n                }\n            }\n        });\n    }\n\n    @Override\n    public void setFirstPage(List<HomeBean.IssueList.ItemList> itemLists) {\n        loading = false;\n        homeAdapter.addData(itemLists);\n    }\n\n    @Override\n    public void setNextPage(List<HomeBean.IssueList.ItemList> itemLists) {\n        loading = false;\n        homeAdapter.addData(itemLists);\n    }\n\n    @Override\n    public void onError(String msg) {\n        ToastUtils.makeToast(msg);\n    }\n\n    @Override\n    public boolean onOptionsItemSelected(MenuItem item) {\n        switch (item.getItemId()) {\n            case android.R.id.home:\n                super.onBackPressed();\n                break;\n        }\n        return super.onOptionsItemSelected(item);\n    }\n}\n"
  },
  {
    "path": "eyepetizer/src/main/java/me/shouheng/eyepetizer/ui/adapter/HomeAdapter.java",
    "content": "package me.shouheng.eyepetizer.ui.adapter;\n\nimport android.content.Context;\nimport android.widget.ImageView;\n\nimport com.bumptech.glide.Glide;\nimport com.chad.library.adapter.base.BaseQuickAdapter;\nimport com.chad.library.adapter.base.BaseViewHolder;\n\nimport java.util.LinkedList;\n\nimport me.shouheng.eyepetizer.R;\nimport me.shouheng.eyepetizer.mvp.model.bean.HomeBean;\n\n/**\n * @author shouh\n * @version $Id: HomeAdapter, v 0.1 2018/8/19 18:19 shouh Exp$\n */\npublic class HomeAdapter extends BaseQuickAdapter<HomeBean.IssueList.ItemList, BaseViewHolder> {\n\n    private Context context;\n\n    public HomeAdapter(Context context) {\n        super(R.layout.item_home, new LinkedList<>());\n        this.context = context;\n    }\n\n    @Override\n    protected void convert(BaseViewHolder helper, HomeBean.IssueList.ItemList item) {\n        helper.setText(R.id.tv_title, item.getData().getTitle());\n        helper.setText(R.id.tv_sub_title, item.getData().getAuthor().getName() + \" | \" + item.getData().getCategory());\n        if (item.getData().getCover() != null) {\n            Glide.with(context)\n                    .load(item.getData().getCover().getHomepage())\n                    .thumbnail(Glide.with(context).load(R.drawable.recommend_summary_card_bg_unlike))\n                    .into((ImageView) helper.getView(R.id.iv_cover));\n        }\n        if (item.getData().getAuthor() != null) {\n            Glide.with(context)\n                    .load(item.getData().getAuthor().getIcon())\n                    .thumbnail(Glide.with(context).load(R.mipmap.eyepetizer))\n                    .into((ImageView) helper.getView(R.id.iv_author));\n        }\n    }\n}\n"
  },
  {
    "path": "eyepetizer/src/main/java/me/shouheng/eyepetizer/ui/fragment/VideoFragment.java",
    "content": "package me.shouheng.eyepetizer.ui.fragment;\n\nimport android.os.Bundle;\nimport android.view.View;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.pili.pldroid.player.widget.PLVideoTextureView;\nimport com.pili.pldroid.player.widget.PLVideoView;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.LogUtils;\nimport me.shouheng.commons.view.fragment.CommonFragment;\nimport me.shouheng.eyepetizer.R;\nimport me.shouheng.eyepetizer.databinding.FragmentEyeVideoBinding;\n\n/**\n * @author shouh\n * @version $Id: VideoFragment, v 0.1 2018/6/9 14:19 shouh Exp$\n */\n@Route(path = BaseConstants.EYEPETIZER_VIDEO)\npublic class VideoFragment extends CommonFragment<FragmentEyeVideoBinding> {\n\n    private String url;\n\n    private boolean fullscreen;\n\n    private int mRotation;\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.fragment_eye_video;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        handleArgument();\n\n        configVideo();\n    }\n\n    private void handleArgument() {\n        Bundle args = getArguments();\n        assert args != null;\n        url = args.getString(BaseConstants.EYEPETIZER_VIDEO_EXTRA_URL);\n        fullscreen = args.getBoolean(BaseConstants.EYEPETIZER_VIDEO_EXTRA_FULLSCREEN);\n    }\n\n    private void configVideo() {\n        LogUtils.d(url);\n        getBinding().vtv.setVideoPath(url);\n        getBinding().vtv.setDisplayOrientation(fullscreen ? PLVideoView.ASPECT_RATIO_PAVED_PARENT : PLVideoView.ASPECT_RATIO_16_9);\n        getBinding().vtv.setOnPreparedListener(plMediaPlayer -> start());\n        getBinding().vtv.setOnBufferingUpdateListener((plMediaPlayer, i) -> LogUtils.d(i + \"\"));\n        getBinding().vtv.setOnCompletionListener(plMediaPlayer -> LogUtils.d(\"completion\"));\n        getBinding().vtv.setOnInfoListener((plMediaPlayer, i, i1) -> {\n            LogUtils.d(i + \"--i1:\" + i1);\n            return false;\n        });\n        getBinding().vtv.setOnErrorListener((plMediaPlayer, i) -> {\n            LogUtils.d(i + \"\");\n            return false;\n        });\n    }\n\n    public void play(String url){\n        this.url = url;\n        getBinding().vtv.setVideoPath(url);\n        getBinding().vtv.start();\n    }\n\n    private void start(){\n        getBinding().vtv.start();\n    }\n\n    public void pause(){\n        getBinding().vtv.pause();\n    }\n\n    public void stopPlayback(){\n        getBinding().vtv.stopPlayback();\n    }\n\n    public void seekTo(long i){\n        getBinding().vtv.seekTo(i);\n    }\n\n    public boolean isPlaying(){\n        return getBinding().vtv.isPlaying();\n    }\n\n    public PLVideoTextureView getVideoView(){\n        return getBinding().vtv;\n    }\n\n    public int getDisplayAspectRatio(){\n        return getBinding().vtv.getDisplayAspectRatio();\n    }\n\n    public void onClickRotate(View v) {\n        mRotation = (getBinding().vtv.getDisplayAspectRatio() + 90) % 360;\n        setDisplayAspectRatio(mRotation);\n    }\n\n    /**\n     * Should be one of below:\n     * {@link PLVideoView#ASPECT_RATIO_4_3}\n     * {@link PLVideoView#ASPECT_RATIO_16_9}\n     * {@link PLVideoView#ASPECT_RATIO_PAVED_PARENT}\n     * {@link PLVideoView#ASPECT_RATIO_FIT_PARENT}\n     * {@link PLVideoView#ASPECT_RATIO_ORIGIN}\n     *\n     * @param ratio see above */\n    public void setDisplayAspectRatio(int ratio){\n        getBinding().vtv.setDisplayAspectRatio(ratio);\n    }\n\n    public void setDisplayOrientation(int orientation){\n        getBinding().vtv.setDisplayOrientation(orientation);\n    }\n\n    @Override\n    public void onResume() {\n        super.onResume();\n        start();\n    }\n\n    @Override\n    public void onPause() {\n        super.onPause();\n        pause();\n    }\n\n    @Override\n    public void onDestroy() {\n        super.onDestroy();\n        stopPlayback();\n    }\n}\n"
  },
  {
    "path": "eyepetizer/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillColor=\"#26A69A\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n"
  },
  {
    "path": "eyepetizer/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillType=\"evenOdd\"\n        android:pathData=\"M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"78.5885\"\n                android:endY=\"90.9159\"\n                android:startX=\"48.7653\"\n                android:startY=\"61.0927\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        android:pathData=\"M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\" />\n</vector>\n"
  },
  {
    "path": "eyepetizer/src/main/res/layout/activity_container.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    tools:context=\".ui.activity.ContainerActivity\">\n\n    <FrameLayout\n        android:id=\"@+id/fragment_container\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"/>\n\n</layout>"
  },
  {
    "path": "eyepetizer/src/main/res/layout/activity_eyepetizer_menu.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    tools:context=\".ui.activity.HomeActivity\">\n\n    <RelativeLayout\n        android:fitsSystemWindows=\"true\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <include android:id=\"@+id/bar_layout\" layout=\"@layout/layout_toolbar\"/>\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/rv\"\n            android:layout_below=\"@id/bar_layout\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"/>\n\n        <View android:layout_below=\"@id/bar_layout\"\n            android:background=\"@drawable/bg_toolbar_shade\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"5dp\"/>\n\n    </RelativeLayout>\n\n</layout>"
  },
  {
    "path": "eyepetizer/src/main/res/layout/fragment_eye_video.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\" >\n\n    <LinearLayout\n        android:orientation=\"vertical\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <com.pili.pldroid.player.widget.PLVideoTextureView\n            android:id=\"@+id/vtv\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:layout_gravity=\"center\" />\n\n    </LinearLayout>\n\n</layout>"
  },
  {
    "path": "eyepetizer/src/main/res/layout/item_home.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.cardview.widget.CardView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_marginBottom=\"8dp\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\">\n\n    <LinearLayout\n        android:orientation=\"vertical\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\">\n\n        <androidx.appcompat.widget.AppCompatImageView\n            android:id=\"@+id/iv_cover\"\n            tools:src=\"@color/black87\"\n            android:scaleType=\"centerCrop\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"150dp\" />\n\n        <LinearLayout\n            android:orientation=\"horizontal\"\n            android:gravity=\"center_vertical\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"50dp\">\n\n            <me.shouheng.commons.view.widget.CircleImageView\n                android:id=\"@+id/iv_author\"\n                android:src=\"@color/colorAccent\"\n                android:layout_marginStart=\"10dp\"\n                android:layout_width=\"40dp\"\n                android:layout_height=\"40dp\" />\n\n            <LinearLayout\n                android:orientation=\"vertical\"\n                android:layout_marginEnd=\"16dp\"\n                android:layout_marginStart=\"10dp\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\">\n\n                <androidx.appcompat.widget.AppCompatTextView\n                    android:id=\"@+id/tv_title\"\n                    android:textSize=\"16sp\"\n                    tools:text=\"Title\"\n                    android:textColor=\"@android:color/black\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatTextView\n                    android:id=\"@+id/tv_sub_title\"\n                    android:textSize=\"@dimen/sp_12\"\n                    tools:text=\"Sub title\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\" />\n\n            </LinearLayout>\n\n        </LinearLayout>\n\n    </LinearLayout>\n\n</androidx.cardview.widget.CardView>"
  },
  {
    "path": "eyepetizer/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "eyepetizer/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "eyepetizer/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">eyepetizer</string>\n</resources>\n"
  },
  {
    "path": "eyepetizer/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "eyepetizer/src/test/java/me/shouheng/eyepetizer/ExampleUnitTest.java",
    "content": "package me.shouheng.eyepetizer;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "guokr/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "guokr/build.gradle",
    "content": "println isGuokrModuleApp.toBoolean()\n\nif (isGuokrModuleApp.toBoolean()) {\n    apply plugin: 'com.android.application'\n} else {\n    apply plugin: 'com.android.library'\n}\n\nandroid {\n    compileSdkVersion rootProject.ext.compileSdkVersion\n    defaultConfig {\n        minSdkVersion rootProject.ext.minSdkVersion\n        targetSdkVersion rootProject.ext.targetSdkVersion\n        versionCode 1\n        versionName \"1.0\"\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n        javaCompileOptions {\n            annotationProcessorOptions {\n                arguments = [ moduleName : project.getName() ]\n            }\n        }\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n    // use data binding\n    dataBinding {\n        enabled = true\n    }\n    // use java 8 language\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n    // use external libs folder\n    sourceSets {\n        main {\n            jniLibs.srcDirs = ['libs']\n            if (isGuokrModuleApp.toBoolean()) {\n                manifest.srcFile \"src/main/debug/AndroidManifest.xml\"\n            } else {\n                manifest.srcFile \"src/main/AndroidManifest.xml\"\n            }\n        }\n    }\n}\n\ndependencies {\n    implementation fileTree(dir: 'libs', include: ['*.jar'])\n    testImplementation 'junit:junit:4.12'\n    androidTestImplementation 'androidx.test:runner:1.1.0'\n    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'\n    // router\n    annotationProcessor 'com.alibaba:arouter-compiler:1.1.4'\n    // projects\n    implementation project(':commons')\n}\n"
  },
  {
    "path": "guokr/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "guokr/src/androidTest/java/me/shouheng/guokr/ExampleInstrumentedTest.java",
    "content": "package me.shouheng.guokr;\n\nimport android.content.Context;\nimport androidx.test.InstrumentationRegistry;\nimport androidx.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"me.shouheng.guokr\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "guokr/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"me.shouheng.guokr\">\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\" >\n\n        <activity android:name=\".view.GuokrNewsActivity\"/>\n\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "guokr/src/main/debug/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"me.shouheng.guokr\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />\n    <uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\" />\n    <uses-permission android:name=\"android.permission.READ_PHONE_STATE\" />\n    <uses-permission android:name=\"android.permission.WAKE_LOCK\" />\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\"\n        android:name=\".ModuleGuokrApp\">\n\n        <activity android:name=\".view.GuokrNewsActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "guokr/src/main/java/me/shouheng/guokr/ModuleGuokrApp.java",
    "content": "package me.shouheng.guokr;\n\nimport com.alibaba.android.arouter.launcher.ARouter;\n\nimport me.shouheng.commons.BaseApplication;\n\n/**\n * @author shouh\n * @version $Id: ModuleGuokrApp, v 0.1 2018/6/6 22:30 shouh Exp$\n */\npublic class ModuleGuokrApp extends BaseApplication {\n\n    private static ModuleGuokrApp application;\n\n    public static ModuleGuokrApp getContext() {\n        return application;\n    }\n\n    @Override\n    public void onCreate() {\n        super.onCreate();\n        application = this;\n\n        ARouter.init(this);\n    }\n}\n"
  },
  {
    "path": "guokr/src/main/java/me/shouheng/guokr/model/data/GuokrNews.java",
    "content": "package me.shouheng.guokr.model.data;\n\nimport java.util.List;\n\n/**\n * @author shouh\n * @version $Id: GuokrNews, v 0.1 2018/6/10 11:13 shouh Exp$\n */\npublic class GuokrNews {\n\n    /**\n     * now : 2018-06-10T14:47:55.517577+08:00\n     * ok : true\n     * limit : 20\n     * result : [{\"image\":\"\",\"is_replyable\":true,\"channels\":[],\"channel_keys\":[],\"preface\":\"\",\"id\":443006,\"subject\":{\"url\":\"http://www.guokr.com/scientific/subject/medicine/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"医学\",\"key\":\"medicine\",\"articles_count\":1819},\"is_editor_recommend\":false,\"copyright\":\"owned_by_guokr\",\"author\":{\"ukey\":\"1jodqq\",\"is_title_authorized\":true,\"nickname\":\"飞刀断雨\",\"master_category\":\"personal\",\"amended_reliability\":\"0\",\"is_exists\":true,\"title\":\"临床医学专业，玄牝之门小组管理员\",\"url\":\"http://www.guokr.com/i/0093516434/\",\"gender\":\"female\",\"followers_count\":221,\"avatar\":{\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"},\"resource_url\":\"http://apis.guokr.com/community/user/1jodqq.json\"},\"image_description\":\"\",\"is_show_summary\":false,\"minisite_key\":\"health\",\"image_info\":{\"url\":\"https://2-im.guokr.com/bfjAMXmfv0qwjQtnzLVOpJt-vu98su4VvVcHR_sUoh9KAQAA8AAAAEpQ.jpg\",\"width\":330,\"height\":240},\"subject_key\":\"medicine\",\"minisite\":{\"name\":\"健康朝九晚五\",\"url\":\"http://www.guokr.com/site/health/\",\"introduction\":\"每天的朝九晚五，上几篇健康小文，有趣、靠谱，还很给力\",\"key\":\"health\",\"date_created\":\"2010-10-20T16:20:43+08:00\",\"icon\":\"https://2-im.guokr.com/gDNaY8kFHIUnyDRLBlb1hWY3fwK9eAuV5icTVSuh7TNuAAAAWgAAAEpQ.jpg\"},\"tags\":[\"转胎药\",\"转胎丸\"],\"date_published\":\"2018-06-08T14:26:01+08:00\",\"video_content\":\"\",\"authors\":[{\"ukey\":\"1jodqq\",\"is_title_authorized\":true,\"nickname\":\"飞刀断雨\",\"master_category\":\"personal\",\"amended_reliability\":\"0\",\"is_exists\":true,\"title\":\"临床医学专业，玄牝之门小组管理员\",\"url\":\"http://www.guokr.com/i/0093516434/\",\"gender\":\"female\",\"followers_count\":221,\"avatar\":{\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"},\"resource_url\":\"http://apis.guokr.com/community/user/1jodqq.json\"}],\"replies_count\":13,\"is_author_external\":false,\"recommends_count\":0,\"title_hide\":\"\\u201c转胎丸\\u201d到底是个什么玩意？\",\"date_modified\":\"2018-06-08T14:59:40.953735+08:00\",\"url\":\"http://www.guokr.com/article/443006/\",\"title\":\"\\u201c转胎丸\\u201d到底是个什么玩意？\",\"small_image\":\"https://2-im.guokr.com/bfjAMXmfv0qwjQtnzLVOpJt-vu98su4VvVcHR_sUoh9KAQAA8AAAAEpQ.jpg\",\"summary\":\"怀孕后吃几颗药，就能保证生男孩？所谓把女胎\\u201c转\\u201d成男胎的\\u201c转胎丸\\u201d，其实已经酿成了不少悲剧。\",\"ukey_author\":\"1jodqq\",\"date_created\":\"2018-06-08T14:26:01+08:00\",\"resource_url\":\"http://apis.guokr.com/minisite/article/443006.json\"},{\"image\":\"\",\"is_replyable\":true,\"channels\":[{\"url\":\"http://www.guokr.com/scientific/channel/visual/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"视觉\",\"key\":\"visual\",\"articles_count\":785}],\"channel_keys\":[\"visual\"],\"preface\":\"\",\"id\":443005,\"subject\":{\"url\":\"http://www.guokr.com/scientific/subject/astronomy/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"天文\",\"key\":\"astronomy\",\"articles_count\":470},\"is_editor_recommend\":false,\"copyright\":\"owned_by_translate\",\"author\":{\"ukey\":\"lnndx5\",\"is_title_authorized\":false,\"nickname\":\"Tisney\",\"master_category\":\"normal\",\"amended_reliability\":\"0\",\"is_exists\":true,\"title\":\"天文本科僧，载人航天工程网小编一枚\",\"url\":\"http://www.guokr.com/i/1309511993/\",\"gender\":null,\"followers_count\":6,\"avatar\":{\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"},\"resource_url\":\"http://apis.guokr.com/community/user/lnndx5.json\"},\"image_description\":\"\",\"is_show_summary\":false,\"minisite_key\":\"sciblog\",\"image_info\":{\"url\":\"https://1-im.guokr.com/FrZnO8axitLRoNyEBsrZDZeJ6OoPwiWtG-DFFlBjCHlKAQAAuQAAAEpQ.jpg\",\"width\":330,\"height\":185},\"subject_key\":\"astronomy\",\"minisite\":{\"name\":\"科技评论\",\"url\":\"http://www.guokr.com/site/sciblog/\",\"introduction\":\"科学与思考是人类前进的两只脚，协同一致，我们才能真正进步\",\"key\":\"sciblog\",\"date_created\":\"2010-10-20T16:20:44+08:00\",\"icon\":\"https://3-im.guokr.com/wUTGS9coWHVZatYqlPTFGo1ig-2JKzSeLNm1FHweYXRuAAAAWgAAAEpQ.jpg\"},\"tags\":[\"火星\",\"好奇号\",\"外星生命\"],\"date_published\":\"2018-06-08T14:00:53+08:00\",\"video_content\":\"\",\"authors\":[{\"ukey\":\"lnndx5\",\"is_title_authorized\":false,\"nickname\":\"Tisney\",\"master_category\":\"normal\",\"amended_reliability\":\"0\",\"is_exists\":true,\"title\":\"天文本科僧，载人航天工程网小编一枚\",\"url\":\"http://www.guokr.com/i/1309511993/\",\"gender\":null,\"followers_count\":6,\"avatar\":{\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"},\"resource_url\":\"http://apis.guokr.com/community/user/lnndx5.json\"}],\"replies_count\":6,\"is_author_external\":false,\"recommends_count\":0,\"title_hide\":\"还没找到火星人，但距离火星生命可能又近了一步\",\"date_modified\":\"2018-06-08T14:00:46.893080+08:00\",\"url\":\"http://www.guokr.com/article/443005/\",\"title\":\"还没找到火星人，但距离火星生命可能又近了一步\",\"small_image\":\"https://1-im.guokr.com/FrZnO8axitLRoNyEBsrZDZeJ6OoPwiWtG-DFFlBjCHlKAQAAuQAAAEpQ.jpg\",\"summary\":\"今天凌晨，NASA召开新闻发布会，公布了好奇号的两项发现：古老的碳留存于火星地表，大气中甲烷存在季节性变化。这两项发现表明，尽管条件恶劣，曾经宜居甚至可能拥有生命的证据，在火星上保存至今的可能性更大了。\",\"ukey_author\":\"lnndx5\",\"date_created\":\"2018-06-08T14:00:53+08:00\",\"resource_url\":\"http://apis.guokr.com/minisite/article/443005.json\"},{\"image\":\"\",\"is_replyable\":true,\"channels\":[],\"channel_keys\":[],\"preface\":\"\",\"id\":443004,\"subject\":{\"url\":\"http://www.guokr.com/scientific/subject/biology/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"生物\",\"key\":\"biology\",\"articles_count\":2635},\"is_editor_recommend\":false,\"copyright\":\"owned_by_guokr\",\"author\":{\"ukey\":\"up508d\",\"is_title_authorized\":false,\"nickname\":\"恐龙杂志\",\"master_category\":\"normal\",\"amended_reliability\":\"0\",\"is_exists\":true,\"title\":\"\",\"url\":\"http://www.guokr.com/i/1856209261/\",\"gender\":null,\"followers_count\":7,\"avatar\":{\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"},\"resource_url\":\"http://apis.guokr.com/community/user/up508d.json\"},\"image_description\":\"\",\"is_show_summary\":false,\"minisite_key\":\"sciblog\",\"image_info\":{\"url\":\"https://2-im.guokr.com/qh1e0_FUxD5z3FWeGS7_aPZeqXJPLL1YjdL-s3I0WSxKAQAAiwAAAEpQ.jpg\",\"width\":330,\"height\":139},\"subject_key\":\"biology\",\"minisite\":{\"name\":\"科技评论\",\"url\":\"http://www.guokr.com/site/sciblog/\",\"introduction\":\"科学与思考是人类前进的两只脚，协同一致，我们才能真正进步\",\"key\":\"sciblog\",\"date_created\":\"2010-10-20T16:20:44+08:00\",\"icon\":\"https://3-im.guokr.com/wUTGS9coWHVZatYqlPTFGo1ig-2JKzSeLNm1FHweYXRuAAAAWgAAAEpQ.jpg\"},\"tags\":[],\"date_published\":\"2018-06-08T12:29:39+08:00\",\"video_content\":\"\",\"authors\":[{\"ukey\":\"up508d\",\"is_title_authorized\":false,\"nickname\":\"恐龙杂志\",\"master_category\":\"normal\",\"amended_reliability\":\"0\",\"is_exists\":true,\"title\":\"\",\"url\":\"http://www.guokr.com/i/1856209261/\",\"gender\":null,\"followers_count\":7,\"avatar\":{\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"},\"resource_url\":\"http://apis.guokr.com/community/user/up508d.json\"}],\"replies_count\":6,\"is_author_external\":false,\"recommends_count\":0,\"title_hide\":\"\\u201c无齿\\u201d和\\u201c不上进\\u201d才是它们躲过大灭绝的秘密武器!?\",\"date_modified\":\"2018-06-08T12:29:36.747972+08:00\",\"url\":\"http://www.guokr.com/article/443004/\",\"title\":\"\\u201c无齿\\u201d和\\u201c不上进\\u201d才是它们躲过大灭绝的秘密武器!?\",\"small_image\":\"https://2-im.guokr.com/qh1e0_FUxD5z3FWeGS7_aPZeqXJPLL1YjdL-s3I0WSxKAQAAiwAAAEpQ.jpg\",\"summary\":\"现今所有的鸟类都来自白垩纪末期很小的一个分支，它们幸存的秘密武器究竟是什么呢？\",\"ukey_author\":\"up508d\",\"date_created\":\"2018-06-08T12:29:39+08:00\",\"resource_url\":\"http://apis.guokr.com/minisite/article/443004.json\"},{\"image\":\"\",\"is_replyable\":true,\"channels\":[{\"url\":\"http://www.guokr.com/scientific/channel/viewpoint/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"观点\",\"key\":\"viewpoint\",\"articles_count\":3804}],\"channel_keys\":[\"viewpoint\"],\"preface\":\"\",\"id\":443003,\"subject\":{\"url\":\"http://www.guokr.com/scientific/subject/society/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"社会\",\"key\":\"society\",\"articles_count\":359},\"is_editor_recommend\":false,\"copyright\":\"owned_by_translate\",\"author\":{\"url\":\"\",\"introduction\":\"BBC News Magazine 特写作者\",\"nickname\":\" Justin Parkinson\",\"avatar\":{\"small\":\"\",\"large\":\"\",\"normal\":\"\"}},\"image_description\":\"\",\"is_show_summary\":false,\"minisite_key\":null,\"image_info\":{\"url\":\"https://2-im.guokr.com/FC6Z5rL6PyaaisM49vyLwf83JgJ4SmM8ssThit5LW8lKAQAA6wAAAFBO.png\",\"width\":330,\"height\":235},\"subject_key\":\"society\",\"minisite\":null,\"tags\":[\"降落伞\",\"极限运动\",\"谋杀\"],\"date_published\":\"2018-06-08T12:08:21.803091+08:00\",\"video_content\":\"\",\"authors\":[{\"introduction\":\"BBC News Magazine 特写作者\",\"url\":\"\",\"nickname\":\" Justin Parkinson\",\"avatar\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png\",\"ukey_author\":null}],\"replies_count\":5,\"is_author_external\":true,\"recommends_count\":0,\"title_hide\":\"降落伞打不开怎么办，急，在线等\",\"date_modified\":\"2018-06-08T12:06:16.629236+08:00\",\"url\":\"http://www.guokr.com/article/443003/\",\"title\":\"降落伞打不开怎么办，急，在线等\",\"small_image\":\"https://2-im.guokr.com/FC6Z5rL6PyaaisM49vyLwf83JgJ4SmM8ssThit5LW8lKAQAA6wAAAFBO.png\",\"summary\":\"看命。\",\"ukey_author\":null,\"date_created\":\"2018-06-08T12:08:21.803091+08:00\",\"resource_url\":\"http://apis.guokr.com/minisite/article/443003.json\"},{\"image\":\"\",\"is_replyable\":true,\"channels\":[],\"channel_keys\":[],\"preface\":\"\",\"id\":443001,\"subject\":{\"url\":\"http://www.guokr.com/scientific/subject/society/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"社会\",\"key\":\"society\",\"articles_count\":359},\"is_editor_recommend\":false,\"copyright\":\"owned_by_translate\",\"author\":{\"url\":\"\",\"introduction\":\"《卫报》特约撰稿人。\",\"nickname\":\"Tim Adams\",\"avatar\":{\"small\":\"https://1-im.guokr.com/HDxt4aEkvhamotPPwV1RKJVF7GgGtzZpWiUCitryj-yMAAAAjAAAAEpQ.jpg\",\"large\":\"https://1-im.guokr.com/HDxt4aEkvhamotPPwV1RKJVF7GgGtzZpWiUCitryj-yMAAAAjAAAAEpQ.jpg\",\"normal\":\"https://1-im.guokr.com/HDxt4aEkvhamotPPwV1RKJVF7GgGtzZpWiUCitryj-yMAAAAjAAAAEpQ.jpg\"}},\"image_description\":\"\",\"is_show_summary\":false,\"minisite_key\":null,\"image_info\":{\"url\":\"https://2-im.guokr.com/uWu7zor-5VxrQfLkd6hJ3Z8gms55a2fbJy6unhkpQxZKAQAA6wAAAEpQ.jpg\",\"width\":330,\"height\":235},\"subject_key\":\"society\",\"minisite\":null,\"tags\":[\"科幻\",\"未来\",\"技术\"],\"date_published\":\"2018-06-08T11:01:31+08:00\",\"video_content\":\"\",\"authors\":[{\"introduction\":\"《卫报》特约撰稿人。\",\"url\":\"\",\"nickname\":\"Tim Adams\",\"avatar\":\"https://1-im.guokr.com/HDxt4aEkvhamotPPwV1RKJVF7GgGtzZpWiUCitryj-yMAAAAjAAAAEpQ.jpg\",\"ukey_author\":null}],\"replies_count\":4,\"is_author_external\":true,\"recommends_count\":0,\"title_hide\":\"超人类的崛起：当人与机器结合\",\"date_modified\":\"2018-06-08T11:08:44.646644+08:00\",\"url\":\"http://www.guokr.com/article/443001/\",\"title\":\"超人类的崛起：当人与机器结合\",\"small_image\":\"https://2-im.guokr.com/uWu7zor-5VxrQfLkd6hJ3Z8gms55a2fbJy6unhkpQxZKAQAA6wAAAEpQ.jpg\",\"summary\":\"身体骇客们正在改造自己的血肉之躯。\",\"ukey_author\":null,\"date_created\":\"2018-06-08T11:01:31+08:00\",\"resource_url\":\"http://apis.guokr.com/minisite/article/443001.json\"},{\"image\":\"\",\"is_replyable\":true,\"channels\":[{\"url\":\"http://www.guokr.com/scientific/channel/frontier/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"前沿\",\"key\":\"frontier\",\"articles_count\":4208}],\"channel_keys\":[\"frontier\"],\"preface\":\"\",\"id\":443002,\"subject\":{\"url\":\"http://www.guokr.com/scientific/subject/internet/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"互联网\",\"key\":\"internet\",\"articles_count\":251},\"is_editor_recommend\":false,\"copyright\":\"owned_by_translate\",\"author\":{\"url\":\"\",\"introduction\":\"自由记者。\",\"nickname\":\"Simon Parkin\",\"avatar\":{\"small\":\"https://2-im.guokr.com/gNdZl2ru102U6qUZN_xIDh3SpHxed4jjvsV_ea2ea0zXAAAA1wAAAFBO.png\",\"large\":\"https://2-im.guokr.com/gNdZl2ru102U6qUZN_xIDh3SpHxed4jjvsV_ea2ea0zXAAAA1wAAAFBO.png\",\"normal\":\"https://2-im.guokr.com/gNdZl2ru102U6qUZN_xIDh3SpHxed4jjvsV_ea2ea0zXAAAA1wAAAFBO.png\"}},\"image_description\":\"\",\"is_show_summary\":false,\"minisite_key\":null,\"image_info\":{\"url\":\"https://2-im.guokr.com/EfUD4zmEojXB7lfAWS-GDhSdt6l-oaBof2EmozPvqONKAQAA6wAAAEpQ.jpg\",\"width\":330,\"height\":235},\"subject_key\":\"internet\",\"minisite\":null,\"tags\":[\"技术\",\"网络\",\"隐私\"],\"date_published\":\"2018-06-08T10:56:56+08:00\",\"video_content\":\"\",\"authors\":[{\"introduction\":\"自由记者。\",\"url\":\"\",\"nickname\":\"Simon Parkin\",\"avatar\":\"https://2-im.guokr.com/gNdZl2ru102U6qUZN_xIDh3SpHxed4jjvsV_ea2ea0zXAAAA1wAAAFBO.png\",\"ukey_author\":null}],\"replies_count\":6,\"is_author_external\":true,\"recommends_count\":0,\"title_hide\":\"如何从互联网上消失，以及你为什么需要从互联网上消失\",\"date_modified\":\"2018-06-08T11:18:24.630700+08:00\",\"url\":\"http://www.guokr.com/article/443002/\",\"title\":\"如何从互联网上消失，以及你为什么需要从互联网上消失\",\"small_image\":\"https://2-im.guokr.com/EfUD4zmEojXB7lfAWS-GDhSdt6l-oaBof2EmozPvqONKAQAA6wAAAEpQ.jpg\",\"summary\":\"成为一个\\u201c数字游魂\\u201d，是非常困难的一件事。\",\"ukey_author\":null,\"date_created\":\"2018-06-08T10:56:56+08:00\",\"resource_url\":\"http://apis.guokr.com/minisite/article/443002.json\"},{\"image\":\"\",\"is_replyable\":true,\"channels\":[{\"url\":\"http://www.guokr.com/scientific/channel/hot/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"热点\",\"key\":\"hot\",\"articles_count\":1921}],\"channel_keys\":[\"hot\"],\"preface\":\"\",\"id\":442999,\"subject\":{\"url\":\"http://www.guokr.com/scientific/subject/medicine/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"医学\",\"key\":\"medicine\",\"articles_count\":1819},\"is_editor_recommend\":false,\"copyright\":\"owned_by_guokr\",\"author\":{\"url\":\"\",\"introduction\":\"首都医科大学附属北京佑安医院感染综合科 副主任医师\",\"nickname\":\"李侗曾\",\"avatar\":{\"small\":\"https://3-im.guokr.com/1iWidzjbRp3tzTfLjC3HL7uVFubrpPNFXogjid00JraQAQAAkAEAAEpQ.jpg\",\"large\":\"https://3-im.guokr.com/1iWidzjbRp3tzTfLjC3HL7uVFubrpPNFXogjid00JraQAQAAkAEAAEpQ.jpg\",\"normal\":\"https://3-im.guokr.com/1iWidzjbRp3tzTfLjC3HL7uVFubrpPNFXogjid00JraQAQAAkAEAAEpQ.jpg\"}},\"image_description\":\"\",\"is_show_summary\":false,\"minisite_key\":\"health\",\"image_info\":{\"url\":\"https://2-im.guokr.com/9nveDubBoCBsFqCWebIsB8cHR1Pud-_Z5jVTnuPATs1KAQAAyAAAAEpQ.jpg\",\"width\":330,\"height\":200},\"subject_key\":\"medicine\",\"minisite\":{\"name\":\"健康朝九晚五\",\"url\":\"http://www.guokr.com/site/health/\",\"introduction\":\"每天的朝九晚五，上几篇健康小文，有趣、靠谱，还很给力\",\"key\":\"health\",\"date_created\":\"2010-10-20T16:20:43+08:00\",\"icon\":\"https://2-im.guokr.com/gDNaY8kFHIUnyDRLBlb1hWY3fwK9eAuV5icTVSuh7TNuAAAAWgAAAEpQ.jpg\"},\"tags\":[],\"date_published\":\"2018-06-06T21:47:08+08:00\",\"video_content\":\"\",\"authors\":[{\"introduction\":\"首都医科大学附属北京佑安医院感染综合科 副主任医师\",\"url\":\"\",\"nickname\":\"李侗曾\",\"avatar\":\"https://3-im.guokr.com/1iWidzjbRp3tzTfLjC3HL7uVFubrpPNFXogjid00JraQAQAAkAEAAEpQ.jpg\",\"ukey_author\":null}],\"replies_count\":7,\"is_author_external\":true,\"recommends_count\":0,\"title_hide\":\"三种HPV疫苗，有什么区别，到底应该怎么选？\",\"date_modified\":\"2018-06-07T16:24:38.680643+08:00\",\"url\":\"http://www.guokr.com/article/442999/\",\"title\":\"三种HPV疫苗，有什么区别，到底应该怎么选？\",\"small_image\":\"https://2-im.guokr.com/9nveDubBoCBsFqCWebIsB8cHR1Pud-_Z5jVTnuPATs1KAQAAyAAAAEpQ.jpg\",\"summary\":\"二价、四价和九价HPV疫苗预防的疾病范围略有不同，它们都安全可靠，按照自己的年龄和经济状况选择即可。\",\"ukey_author\":null,\"date_created\":\"2018-06-06T21:47:08+08:00\",\"resource_url\":\"http://apis.guokr.com/minisite/article/442999.json\"},{\"image\":\"\",\"is_replyable\":true,\"channels\":[],\"channel_keys\":[],\"preface\":\"\",\"id\":443000,\"subject\":{\"url\":\"http://www.guokr.com/scientific/subject/society/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"社会\",\"key\":\"society\",\"articles_count\":359},\"is_editor_recommend\":false,\"copyright\":\"owned_by_guokr\",\"author\":{\"url\":\"\",\"introduction\":\"食品工程博士 心理学博士 商学院教授\",\"nickname\":\"崔凯\",\"avatar\":{\"small\":\"https://3-im.guokr.com/aD-5u3s3s_rFfh9oZ0LvRSU2tA6ITe2eSWbncnhjMouiAAAApAAAAEpQ.jpg\",\"large\":\"https://3-im.guokr.com/aD-5u3s3s_rFfh9oZ0LvRSU2tA6ITe2eSWbncnhjMouiAAAApAAAAEpQ.jpg\",\"normal\":\"https://3-im.guokr.com/aD-5u3s3s_rFfh9oZ0LvRSU2tA6ITe2eSWbncnhjMouiAAAApAAAAEpQ.jpg\"}},\"image_description\":\"\",\"is_show_summary\":false,\"minisite_key\":null,\"image_info\":{\"url\":\"https://3-im.guokr.com/uNuse-S5JHSZkahoWm7coiib-twvRko2QN2EN34WuiBKAQAA3AAAAEpQ.jpg\",\"width\":330,\"height\":220},\"subject_key\":\"society\",\"minisite\":null,\"tags\":[],\"date_published\":\"2018-06-06T16:41:01+08:00\",\"video_content\":\"<iframe frameborder=\\\"0\\\" width=\\\"640\\\" height=\\\"498\\\" src=\\\"https://v.qq.com/iframe/player.html?vid=w067813pbwp&tiny=0&auto=0\\\" allowfullscreen><\\/iframe>\",\"authors\":[{\"introduction\":\"食品工程博士 心理学博士 商学院教授\",\"url\":\"\",\"nickname\":\"崔凯\",\"avatar\":\"https://3-im.guokr.com/aD-5u3s3s_rFfh9oZ0LvRSU2tA6ITe2eSWbncnhjMouiAAAApAAAAEpQ.jpg\",\"ukey_author\":null}],\"replies_count\":26,\"is_author_external\":true,\"recommends_count\":0,\"title_hide\":\"关于转基因，你的担忧科学吗？\",\"date_modified\":\"2018-06-06T16:46:04.112405+08:00\",\"url\":\"http://www.guokr.com/article/443000/\",\"title\":\"关于转基因，你的担忧科学吗？\",\"small_image\":\"https://3-im.guokr.com/uNuse-S5JHSZkahoWm7coiib-twvRko2QN2EN34WuiBKAQAA3AAAAEpQ.jpg\",\"summary\":\"不妨先听听最权威的科学机构怎么说？\",\"ukey_author\":null,\"date_created\":\"2018-06-06T16:41:01+08:00\",\"resource_url\":\"http://apis.guokr.com/minisite/article/443000.json\"},{\"image\":\"\",\"is_replyable\":true,\"channels\":[{\"url\":\"http://www.guokr.com/scientific/channel/viewpoint/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"观点\",\"key\":\"viewpoint\",\"articles_count\":3804}],\"channel_keys\":[\"viewpoint\"],\"preface\":\"\",\"id\":442995,\"subject\":{\"url\":\"http://www.guokr.com/scientific/subject/biology/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"生物\",\"key\":\"biology\",\"articles_count\":2635},\"is_editor_recommend\":false,\"copyright\":\"owned_by_guokr\",\"author\":{\"ukey\":\"2dxj2y\",\"is_title_authorized\":false,\"nickname\":\"vicko238\",\"master_category\":\"normal\",\"amended_reliability\":\"0\",\"is_exists\":true,\"title\":\"\",\"url\":\"http://www.guokr.com/i/0144331738/\",\"gender\":null,\"followers_count\":0,\"avatar\":{\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"},\"resource_url\":\"http://apis.guokr.com/community/user/2dxj2y.json\"},\"image_description\":\"\",\"is_show_summary\":false,\"minisite_key\":\"sciblog\",\"image_info\":{\"url\":\"https://3-im.guokr.com/DkQqbsE2HEoGeU3EusujidqlScGz_ABiIgd9arB-WiFKAQAA6wAAAEpQ.jpg\",\"width\":330,\"height\":235},\"subject_key\":\"biology\",\"minisite\":{\"name\":\"科技评论\",\"url\":\"http://www.guokr.com/site/sciblog/\",\"introduction\":\"科学与思考是人类前进的两只脚，协同一致，我们才能真正进步\",\"key\":\"sciblog\",\"date_created\":\"2010-10-20T16:20:44+08:00\",\"icon\":\"https://3-im.guokr.com/wUTGS9coWHVZatYqlPTFGo1ig-2JKzSeLNm1FHweYXRuAAAAWgAAAEpQ.jpg\"},\"tags\":[\"铲形门齿\",\"考古\",\"白令陆桥\",\"最后盛冰期\"],\"date_published\":\"2018-06-06T16:32:46+08:00\",\"video_content\":\"\",\"authors\":[{\"ukey\":\"2dxj2y\",\"is_title_authorized\":false,\"nickname\":\"vicko238\",\"master_category\":\"normal\",\"amended_reliability\":\"0\",\"is_exists\":true,\"title\":\"\",\"url\":\"http://www.guokr.com/i/0144331738/\",\"gender\":null,\"followers_count\":0,\"avatar\":{\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"},\"resource_url\":\"http://apis.guokr.com/community/user/2dxj2y.json\"}],\"replies_count\":14,\"is_author_external\":false,\"recommends_count\":0,\"title_hide\":\"门牙两边有个楞，你告诉我是东亚人变异？它有个毛用？\",\"date_modified\":\"2018-06-07T18:17:12.416990+08:00\",\"url\":\"http://www.guokr.com/article/442995/\",\"title\":\"门牙两边有个楞，你告诉我是东亚人变异？它有个毛用？\",\"small_image\":\"https://3-im.guokr.com/DkQqbsE2HEoGeU3EusujidqlScGz_ABiIgd9arB-WiFKAQAA6wAAAEpQ.jpg\",\"summary\":\"排汗？保湿？补充婴儿维生素D？\",\"ukey_author\":\"2dxj2y\",\"date_created\":\"2018-06-06T16:32:46+08:00\",\"resource_url\":\"http://apis.guokr.com/minisite/article/442995.json\"},{\"image\":\"\",\"is_replyable\":true,\"channels\":[],\"channel_keys\":[],\"preface\":\"\",\"id\":442998,\"subject\":{\"url\":\"http://www.guokr.com/scientific/subject/others/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"其他\",\"key\":\"others\",\"articles_count\":291},\"is_editor_recommend\":false,\"copyright\":\"owned_by_translate\",\"author\":{\"url\":\"\",\"introduction\":\"Live Science资深作者\",\"nickname\":\"Mindy Weisberger \",\"avatar\":{\"small\":\"https://media.licdn.com/dms/image/C4D03AQF7xRtHc4noOQ/profile-displayphoto-shrink_800_800/0?e=1533772800&v=beta&t=MDD5Km5I87EaBD4nHZLfsCMrISUU1LH7lN6WlvCA7MI\",\"large\":\"https://media.licdn.com/dms/image/C4D03AQF7xRtHc4noOQ/profile-displayphoto-shrink_800_800/0?e=1533772800&v=beta&t=MDD5Km5I87EaBD4nHZLfsCMrISUU1LH7lN6WlvCA7MI\",\"normal\":\"https://media.licdn.com/dms/image/C4D03AQF7xRtHc4noOQ/profile-displayphoto-shrink_800_800/0?e=1533772800&v=beta&t=MDD5Km5I87EaBD4nHZLfsCMrISUU1LH7lN6WlvCA7MI\"}},\"image_description\":\"\",\"is_show_summary\":false,\"minisite_key\":null,\"image_info\":{\"url\":\"https://2-im.guokr.com/Y3XGb0iiy4Om61rSah6LOXrO0PXklfOK2mX-Iir-VTFKAQAA6wAAAEpQ.jpg\",\"width\":330,\"height\":235},\"subject_key\":\"others\",\"minisite\":null,\"tags\":[\"语言\",\"演讲\",\"停顿\",\"名词\",\"动词\"],\"date_published\":\"2018-06-06T14:20:32.834522+08:00\",\"video_content\":\"\",\"authors\":[{\"introduction\":\"Live Science资深作者\",\"url\":\"\",\"nickname\":\"Mindy Weisberger \",\"avatar\":\"https://media.licdn.com/dms/image/C4D03AQF7xRtHc4noOQ/profile-displayphoto-shrink_800_800/0?e=1533772800&v=beta&t=MDD5Km5I87EaBD4nHZLfsCMrISUU1LH7lN6WlvCA7MI\",\"ukey_author\":null}],\"replies_count\":5,\"is_author_external\":true,\"recommends_count\":2,\"title_hide\":\"虽然人们说着不同的语言，但卡壳的地方都一样一样的\",\"date_modified\":\"2018-06-05T18:20:31.303349+08:00\",\"url\":\"http://www.guokr.com/article/442998/\",\"title\":\"虽然人们说着不同的语言，但卡壳的地方都一样一样的\",\"small_image\":\"https://2-im.guokr.com/Y3XGb0iiy4Om61rSah6LOXrO0PXklfOK2mX-Iir-VTFKAQAA6wAAAEpQ.jpg\",\"summary\":\"这个地方就是：名词之前\\u2026\\u2026\",\"ukey_author\":null,\"date_created\":\"2018-06-06T14:20:32.834522+08:00\",\"resource_url\":\"http://apis.guokr.com/minisite/article/442998.json\"},{\"image\":\"\",\"is_replyable\":true,\"channels\":[],\"channel_keys\":[],\"preface\":\"\",\"id\":442997,\"subject\":{\"url\":\"http://www.guokr.com/scientific/subject/environment/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"环境\",\"key\":\"environment\",\"articles_count\":371},\"is_editor_recommend\":false,\"copyright\":\"owned_by_guokr\",\"author\":{\"ukey\":\"ew2xfi\",\"is_title_authorized\":false,\"nickname\":\"半个书生\",\"master_category\":\"normal\",\"amended_reliability\":\"0\",\"is_exists\":true,\"title\":\"\",\"url\":\"http://www.guokr.com/i/0900410814/\",\"gender\":null,\"followers_count\":4,\"avatar\":{\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"},\"resource_url\":\"http://apis.guokr.com/community/user/ew2xfi.json\"},\"image_description\":\"\",\"is_show_summary\":false,\"minisite_key\":\"natural\",\"image_info\":{\"url\":\"https://1-im.guokr.com/1xnCnvbMM30VaBFClNsHOmYeDaNE3RIka-Vg3FUeCXJKAQAA0QAAAEpQ.jpg\",\"width\":330,\"height\":209},\"subject_key\":\"environment\",\"minisite\":{\"name\":\"自然控\",\"url\":\"http://www.guokr.com/site/natural/\",\"introduction\":\"让我们一起来分享花草树木、鸟兽虫鱼，还有灿烂星河带来的喜悦，以博物精神之名\",\"key\":\"natural\",\"date_created\":\"2010-10-20T16:20:44+08:00\",\"icon\":\"https://1-im.guokr.com/szAPyph4MN164v0f72VQmTKrP5u6_ADO3iTBqkDYLetuAAAAWgAAAEpQ.jpg\"},\"tags\":[],\"date_published\":\"2018-06-05T17:07:37+08:00\",\"video_content\":\"\",\"authors\":[{\"ukey\":\"ew2xfi\",\"is_title_authorized\":false,\"nickname\":\"半个书生\",\"master_category\":\"normal\",\"amended_reliability\":\"0\",\"is_exists\":true,\"title\":\"\",\"url\":\"http://www.guokr.com/i/0900410814/\",\"gender\":null,\"followers_count\":4,\"avatar\":{\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"},\"resource_url\":\"http://apis.guokr.com/community/user/ew2xfi.json\"}],\"replies_count\":11,\"is_author_external\":false,\"recommends_count\":1,\"title_hide\":\"保护区：哪有什么岁月静好，只有你不知道的现状\",\"date_modified\":\"2018-06-05T17:12:56.237099+08:00\",\"url\":\"http://www.guokr.com/article/442997/\",\"title\":\"保护区：哪有什么岁月静好，只有你不知道的现状\",\"small_image\":\"https://1-im.guokr.com/1xnCnvbMM30VaBFClNsHOmYeDaNE3RIka-Vg3FUeCXJKAQAA0QAAAEpQ.jpg\",\"summary\":\"我们不能等到和其他物种都告别之后，才懂得孤独的真正意义。\",\"ukey_author\":\"ew2xfi\",\"date_created\":\"2018-06-05T17:07:37+08:00\",\"resource_url\":\"http://apis.guokr.com/minisite/article/442997.json\"},{\"image\":\"\",\"is_replyable\":true,\"channels\":[{\"url\":\"http://www.guokr.com/scientific/channel/hot/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"热点\",\"key\":\"hot\",\"articles_count\":1921}],\"channel_keys\":[\"hot\"],\"preface\":\"\",\"id\":442996,\"subject\":{\"url\":\"http://www.guokr.com/scientific/subject/society/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"社会\",\"key\":\"society\",\"articles_count\":359},\"is_editor_recommend\":false,\"copyright\":\"owned_by_guokr\",\"author\":{\"ukey\":\"l0q7lu\",\"is_title_authorized\":true,\"nickname\":\"李子李子短信\",\"master_category\":\"personal\",\"amended_reliability\":\"0\",\"is_exists\":true,\"title\":\"社科硕士，博物馆爱好者，果壳作者\",\"url\":\"http://www.guokr.com/i/1271012610/\",\"gender\":\"male\",\"followers_count\":3997,\"avatar\":{\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"},\"resource_url\":\"http://apis.guokr.com/community/user/l0q7lu.json\"},\"image_description\":\"\",\"is_show_summary\":true,\"minisite_key\":null,\"image_info\":{\"url\":\"https://2-im.guokr.com/1E9vgXXx2D5oYiHWxtRwAMjnOVxg0ha0-kD6uYy_74JKAQAA6wAAAEpQ.jpg\",\"width\":330,\"height\":235},\"subject_key\":\"society\",\"minisite\":null,\"tags\":[\"苹果\",\"技术\",\"WWDC\",\"软件\",\"升级\",\"IOS\"],\"date_published\":\"2018-06-05T16:57:37+08:00\",\"video_content\":\"\",\"authors\":[{\"ukey\":\"l0q7lu\",\"is_title_authorized\":true,\"nickname\":\"李子李子短信\",\"master_category\":\"personal\",\"amended_reliability\":\"0\",\"is_exists\":true,\"title\":\"社科硕士，博物馆爱好者，果壳作者\",\"url\":\"http://www.guokr.com/i/1271012610/\",\"gender\":\"male\",\"followers_count\":3997,\"avatar\":{\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"},\"resource_url\":\"http://apis.guokr.com/community/user/l0q7lu.json\"}],\"replies_count\":8,\"is_author_external\":false,\"recommends_count\":0,\"title_hide\":\"听说昨晚苹果只发布了彩虹表带？同学，软件升级了解一下？\",\"date_modified\":\"2018-06-06T13:26:02.767025+08:00\",\"url\":\"http://www.guokr.com/article/442996/\",\"title\":\"听说昨晚苹果只发布了彩虹表带？同学，软件升级了解一下？\",\"small_image\":\"https://2-im.guokr.com/1E9vgXXx2D5oYiHWxtRwAMjnOVxg0ha0-kD6uYy_74JKAQAA6wAAAEpQ.jpg\",\"summary\":\"我们不贩卖焦虑，我们是焦虑的搬运工，左手搬到右手，从手机搬到手表\\u2026\\u2026\",\"ukey_author\":\"l0q7lu\",\"date_created\":\"2018-06-05T16:57:37+08:00\",\"resource_url\":\"http://apis.guokr.com/minisite/article/442996.json\"},{\"image\":\"\",\"is_replyable\":true,\"channels\":[],\"channel_keys\":[],\"preface\":\"\",\"id\":442992,\"subject\":{\"url\":\"http://www.guokr.com/scientific/subject/medicine/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"医学\",\"key\":\"medicine\",\"articles_count\":1819},\"is_editor_recommend\":false,\"copyright\":\"owned_by_translate\",\"author\":{\"url\":\"\",\"introduction\":\"加州大学洛杉矶分校，麻醉与术期医学临床副教授\",\"nickname\":\"Karen Sibert\",\"avatar\":{\"small\":\"https://cdn.theconversation.com/avatars/453390/width238/Karen-Sibert.jpg\",\"large\":\"https://cdn.theconversation.com/avatars/453390/width238/Karen-Sibert.jpg\",\"normal\":\"https://cdn.theconversation.com/avatars/453390/width238/Karen-Sibert.jpg\"}},\"image_description\":\"\",\"is_show_summary\":false,\"minisite_key\":\"health\",\"image_info\":{\"url\":\"https://3-im.guokr.com/DJRS-0GhDZ7Is6nlLF3UzWqjqXdgXOHuV-0u5vh8-49KAQAA6wAAAEpQ.jpg\",\"width\":330,\"height\":235},\"subject_key\":\"medicine\",\"minisite\":{\"name\":\"健康朝九晚五\",\"url\":\"http://www.guokr.com/site/health/\",\"introduction\":\"每天的朝九晚五，上几篇健康小文，有趣、靠谱，还很给力\",\"key\":\"health\",\"date_created\":\"2010-10-20T16:20:43+08:00\",\"icon\":\"https://2-im.guokr.com/gDNaY8kFHIUnyDRLBlb1hWY3fwK9eAuV5icTVSuh7TNuAAAAWgAAAEpQ.jpg\"},\"tags\":[\"疼痛\",\"痛觉\",\"麻醉\",\"止痛药\",\"镇痛药\",\"种族\"],\"date_published\":\"2018-06-05T13:36:35.703241+08:00\",\"video_content\":\"\",\"authors\":[{\"introduction\":\"加州大学洛杉矶分校，麻醉与术期医学临床副教授\",\"url\":\"\",\"nickname\":\"Karen Sibert\",\"avatar\":\"https://cdn.theconversation.com/avatars/453390/width238/Karen-Sibert.jpg\",\"ukey_author\":null}],\"replies_count\":7,\"is_author_external\":true,\"recommends_count\":0,\"title_hide\":\"有种痛叫做别人觉得你不痛\",\"date_modified\":\"2018-06-04T17:23:19.375812+08:00\",\"url\":\"http://www.guokr.com/article/442992/\",\"title\":\"有种痛叫做别人觉得你不痛\",\"small_image\":\"https://3-im.guokr.com/DJRS-0GhDZ7Is6nlLF3UzWqjqXdgXOHuV-0u5vh8-49KAQAA6wAAAEpQ.jpg\",\"summary\":\"生理条件不一样，疼法和待遇可能也不一样\\u2026\\u2026\",\"ukey_author\":null,\"date_created\":\"2018-06-05T13:36:35.703241+08:00\",\"resource_url\":\"http://apis.guokr.com/minisite/article/442992.json\"},{\"image\":\"\",\"is_replyable\":true,\"channels\":[{\"url\":\"http://www.guokr.com/scientific/channel/frontier/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"前沿\",\"key\":\"frontier\",\"articles_count\":4208}],\"channel_keys\":[\"frontier\"],\"preface\":\"\",\"id\":442994,\"subject\":{\"url\":\"http://www.guokr.com/scientific/subject/society/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"社会\",\"key\":\"society\",\"articles_count\":359},\"is_editor_recommend\":false,\"copyright\":\"owned_by_guokr\",\"author\":{\"url\":\"\",\"introduction\":\"\",\"nickname\":\"李子李子短信\",\"avatar\":{\"small\":\"\",\"large\":\"\",\"normal\":\"\"}},\"image_description\":\"\",\"is_show_summary\":false,\"minisite_key\":null,\"image_info\":{\"url\":\"https://2-im.guokr.com/fmsNyqU_vMGiiPK3ndx-qKqib_y5tZqS-QKPpL9RuUFKAQAA6wAAAFBO.png\",\"width\":330,\"height\":235},\"subject_key\":\"society\",\"minisite\":null,\"tags\":[\"学术不端\",\"数据造假\",\"撤稿\",\"心理学\"],\"date_published\":\"2018-06-05T13:14:26+08:00\",\"video_content\":\"\",\"authors\":[{\"introduction\":\"\",\"url\":\"\",\"nickname\":\"李子李子短信\",\"avatar\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png\",\"ukey_author\":null}],\"replies_count\":14,\"is_author_external\":true,\"recommends_count\":1,\"title_hide\":\"两个\\u201c数据流氓\\u201d如何掀翻学术大佬\",\"date_modified\":\"2018-06-05T15:14:28.900475+08:00\",\"url\":\"http://www.guokr.com/article/442994/\",\"title\":\"两个\\u201c数据流氓\\u201d如何掀翻学术大佬\",\"small_image\":\"https://2-im.guokr.com/fmsNyqU_vMGiiPK3ndx-qKqib_y5tZqS-QKPpL9RuUFKAQAA6wAAAFBO.png\",\"summary\":\"他们把数据简单跑了一遍，发现令人哈哈哈的bug竟然满天飞？！\",\"ukey_author\":null,\"date_created\":\"2018-06-05T13:14:26+08:00\",\"resource_url\":\"http://apis.guokr.com/minisite/article/442994.json\"},{\"image\":\"\",\"is_replyable\":true,\"channels\":[{\"url\":\"http://www.guokr.com/scientific/channel/viewpoint/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"观点\",\"key\":\"viewpoint\",\"articles_count\":3804}],\"channel_keys\":[\"viewpoint\"],\"preface\":\"\",\"id\":442993,\"subject\":{\"url\":\"http://www.guokr.com/scientific/subject/medicine/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"医学\",\"key\":\"medicine\",\"articles_count\":1819},\"is_editor_recommend\":false,\"copyright\":\"owned_by_cooperation\",\"author\":{\"url\":\"\",\"introduction\":\"麻州大学医学院助理教授，美国执业视光医生。\",\"nickname\":\"丁娟\",\"avatar\":{\"small\":\"http://1-im.guokr.com/V09B9eFMErb_rLUIm3MtvjNxXdI8CHI_pvy5iTj21bebAgAAmwIAAEpQ.jpg\",\"large\":\"http://1-im.guokr.com/V09B9eFMErb_rLUIm3MtvjNxXdI8CHI_pvy5iTj21bebAgAAmwIAAEpQ.jpg\",\"normal\":\"http://1-im.guokr.com/V09B9eFMErb_rLUIm3MtvjNxXdI8CHI_pvy5iTj21bebAgAAmwIAAEpQ.jpg\"}},\"image_description\":\"\",\"is_show_summary\":false,\"minisite_key\":\"health\",\"image_info\":{\"url\":\"https://1-im.guokr.com/YJ98vfWsDX3EtM-sxz1smgbG1gP9wSp6x3NgwaW3zPNKAQAA8AAAAEpQ.jpg\",\"width\":330,\"height\":240},\"subject_key\":\"medicine\",\"minisite\":{\"name\":\"健康朝九晚五\",\"url\":\"http://www.guokr.com/site/health/\",\"introduction\":\"每天的朝九晚五，上几篇健康小文，有趣、靠谱，还很给力\",\"key\":\"health\",\"date_created\":\"2010-10-20T16:20:43+08:00\",\"icon\":\"https://2-im.guokr.com/gDNaY8kFHIUnyDRLBlb1hWY3fwK9eAuV5icTVSuh7TNuAAAAWgAAAEpQ.jpg\"},\"tags\":[],\"date_published\":\"2018-06-05T08:49:40+08:00\",\"video_content\":\"\",\"authors\":[{\"introduction\":\"麻州大学医学院助理教授，美国执业视光医生。\",\"url\":\"\",\"nickname\":\"丁娟\",\"avatar\":\"http://1-im.guokr.com/V09B9eFMErb_rLUIm3MtvjNxXdI8CHI_pvy5iTj21bebAgAAmwIAAEpQ.jpg\",\"ukey_author\":null}],\"replies_count\":13,\"is_author_external\":true,\"recommends_count\":0,\"title_hide\":\"关于近视的所有疑问，读这一篇就够了\",\"date_modified\":\"2018-06-05T08:49:37.437741+08:00\",\"url\":\"http://www.guokr.com/article/442993/\",\"title\":\"关于近视的所有疑问，读这一篇就够了\",\"small_image\":\"https://1-im.guokr.com/YJ98vfWsDX3EtM-sxz1smgbG1gP9wSp6x3NgwaW3zPNKAQAA8AAAAEpQ.jpg\",\"summary\":\"怎么预防？如何治疗？哪些方法靠谱？一分钱不花也可以预防近视？发现小孩近视怎么办？在近视初期，不戴近视眼镜，或者戴度数浅的眼镜，有帮助吗？所谓\\u201c逆转近视，缩短眼轴\\u201d，是不是在骗人？\",\"ukey_author\":null,\"date_created\":\"2018-06-05T08:49:40+08:00\",\"resource_url\":\"http://apis.guokr.com/minisite/article/442993.json\"},{\"image\":\"\",\"is_replyable\":true,\"channels\":[{\"url\":\"http://www.guokr.com/scientific/channel/viewpoint/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"观点\",\"key\":\"viewpoint\",\"articles_count\":3804}],\"channel_keys\":[\"viewpoint\"],\"preface\":\"\",\"id\":442990,\"subject\":{\"url\":\"http://www.guokr.com/scientific/subject/medicine/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"医学\",\"key\":\"medicine\",\"articles_count\":1819},\"is_editor_recommend\":false,\"copyright\":\"owned_by_guokr\",\"author\":{\"ukey\":\"07z00a\",\"is_title_authorized\":true,\"nickname\":\"MarvinP\",\"master_category\":\"personal\",\"amended_reliability\":\"0\",\"is_exists\":true,\"title\":\"遗传学博士生，科学松鼠会成员，科普专栏作者\",\"url\":\"http://www.guokr.com/i/0013390282/\",\"gender\":null,\"followers_count\":3138,\"avatar\":{\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"},\"resource_url\":\"http://apis.guokr.com/community/user/07z00a.json\"},\"image_description\":\"\",\"is_show_summary\":false,\"minisite_key\":\"health\",\"image_info\":{\"url\":\"https://3-im.guokr.com/LDuegVH3d_2EiC5ibszbOFrLYuVXHLBIcNrFp5y30JBKAQAA5gAAAEpQ.jpg\",\"width\":330,\"height\":230},\"subject_key\":\"medicine\",\"minisite\":{\"name\":\"健康朝九晚五\",\"url\":\"http://www.guokr.com/site/health/\",\"introduction\":\"每天的朝九晚五，上几篇健康小文，有趣、靠谱，还很给力\",\"key\":\"health\",\"date_created\":\"2010-10-20T16:20:43+08:00\",\"icon\":\"https://2-im.guokr.com/gDNaY8kFHIUnyDRLBlb1hWY3fwK9eAuV5icTVSuh7TNuAAAAWgAAAEpQ.jpg\"},\"tags\":[],\"date_published\":\"2018-06-02T18:38:19+08:00\",\"video_content\":\"\",\"authors\":[{\"ukey\":\"07z00a\",\"is_title_authorized\":true,\"nickname\":\"MarvinP\",\"master_category\":\"personal\",\"amended_reliability\":\"0\",\"is_exists\":true,\"title\":\"遗传学博士生，科学松鼠会成员，科普专栏作者\",\"url\":\"http://www.guokr.com/i/0013390282/\",\"gender\":null,\"followers_count\":3138,\"avatar\":{\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"},\"resource_url\":\"http://apis.guokr.com/community/user/07z00a.json\"}],\"replies_count\":9,\"is_author_external\":false,\"recommends_count\":0,\"title_hide\":\"得了癌症以后，生活会发生巨变，但你依然是你\",\"date_modified\":\"2018-06-02T20:11:16.296653+08:00\",\"url\":\"http://www.guokr.com/article/442990/\",\"title\":\"得了癌症以后，生活会发生巨变，但你依然是你\",\"small_image\":\"https://3-im.guokr.com/LDuegVH3d_2EiC5ibszbOFrLYuVXHLBIcNrFp5y30JBKAQAA5gAAAEpQ.jpg\",\"summary\":\"电影《湮灭》可以看成是关于癌症和癌症幸存者的贴切譬喻。\",\"ukey_author\":\"07z00a\",\"date_created\":\"2018-06-02T18:38:19+08:00\",\"resource_url\":\"http://apis.guokr.com/minisite/article/442990.json\"},{\"image\":\"\",\"is_replyable\":true,\"channels\":[],\"channel_keys\":[],\"preface\":\"\",\"id\":442989,\"subject\":{\"url\":\"http://www.guokr.com/scientific/subject/electronics/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"电子\",\"key\":\"electronics\",\"articles_count\":780},\"is_editor_recommend\":false,\"copyright\":\"owned_by_guokr\",\"author\":{\"url\":\"\",\"introduction\":\"脑机接口界的小动物爱好者，可穿戴传感设备界的灵魂画手，人工智障技术研究员。\",\"nickname\":\"莘莘\",\"avatar\":{\"small\":\"https://1-im.guokr.com/ePxGTDWqC9fu8OfQ74-bif19D7TZg78Qu45s0Jep_-T8AAAA_gAAAEpQ.jpg\",\"large\":\"https://1-im.guokr.com/ePxGTDWqC9fu8OfQ74-bif19D7TZg78Qu45s0Jep_-T8AAAA_gAAAEpQ.jpg\",\"normal\":\"https://1-im.guokr.com/ePxGTDWqC9fu8OfQ74-bif19D7TZg78Qu45s0Jep_-T8AAAA_gAAAEpQ.jpg\"}},\"image_description\":\"\",\"is_show_summary\":false,\"minisite_key\":\"digest\",\"image_info\":{\"url\":\"https://3-im.guokr.com/yfLagAzgHeXKu1STC8XfwlCN8W_hFEot-cLXZrQBuItKAQAABwEAAEpQ.jpg\",\"width\":330,\"height\":263},\"subject_key\":\"electronics\",\"minisite\":{\"name\":\"环球科技观光团\",\"url\":\"http://www.guokr.com/site/digest/\",\"introduction\":\"这里报道最新、最酷的资讯，带你快速了解世界科研一线成就\",\"key\":\"digest\",\"date_created\":\"2010-10-20T16:20:44+08:00\",\"icon\":\"https://3-im.guokr.com/TPdfxoaxAGOhbhf2mHZsjvnXSCsT8dtGv0ItDjLiAmBuAAAAWgAAAEpQ.jpg\"},\"tags\":[],\"date_published\":\"2018-06-01T14:24:49+08:00\",\"video_content\":\"\",\"authors\":[{\"introduction\":\"脑机接口界的小动物爱好者，可穿戴传感设备界的灵魂画手，人工智障技术研究员。\",\"url\":\"\",\"nickname\":\"莘莘\",\"avatar\":\"https://1-im.guokr.com/ePxGTDWqC9fu8OfQ74-bif19D7TZg78Qu45s0Jep_-T8AAAA_gAAAEpQ.jpg\",\"ukey_author\":null}],\"replies_count\":6,\"is_author_external\":true,\"recommends_count\":0,\"title_hide\":\"这个儿童节，我可以拥有哆啦A梦了吗？\",\"date_modified\":\"2018-06-01T14:26:43.432511+08:00\",\"url\":\"http://www.guokr.com/article/442989/\",\"title\":\"这个儿童节，我可以拥有哆啦A梦了吗？\",\"small_image\":\"https://3-im.guokr.com/yfLagAzgHeXKu1STC8XfwlCN8W_hFEot-cLXZrQBuItKAQAABwEAAEpQ.jpg\",\"summary\":\"想得美！\",\"ukey_author\":null,\"date_created\":\"2018-06-01T14:24:49+08:00\",\"resource_url\":\"http://apis.guokr.com/minisite/article/442989.json\"},{\"image\":\"\",\"is_replyable\":true,\"channels\":[],\"channel_keys\":[],\"preface\":\"\",\"id\":442988,\"subject\":{\"url\":\"http://www.guokr.com/scientific/subject/others/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"其他\",\"key\":\"others\",\"articles_count\":291},\"is_editor_recommend\":false,\"copyright\":\"owned_by_guokr\",\"author\":{\"url\":\"\",\"introduction\":\"中国科普研究所\",\"nickname\":\"王大鹏\",\"avatar\":{\"small\":\"https://2-im.guokr.com/ddVa-TCvjjcfMAyF74vXi_SIm0Do-bqZNl5iEh9ZZMr_AAAAAAEAAEpQ.jpg\",\"large\":\"https://2-im.guokr.com/ddVa-TCvjjcfMAyF74vXi_SIm0Do-bqZNl5iEh9ZZMr_AAAAAAEAAEpQ.jpg\",\"normal\":\"https://2-im.guokr.com/ddVa-TCvjjcfMAyF74vXi_SIm0Do-bqZNl5iEh9ZZMr_AAAAAAEAAEpQ.jpg\"}},\"image_description\":\"\",\"is_show_summary\":false,\"minisite_key\":null,\"image_info\":{\"url\":\"https://1-im.guokr.com/BKRFIIBHToe-2gqv9dV1UQ_vJ6lx0Dr9ksYbPM-OqO9KAQAAoAAAAEpQ.jpg\",\"width\":330,\"height\":160},\"subject_key\":\"others\",\"minisite\":null,\"tags\":[],\"date_published\":\"2018-05-31T16:12:37+08:00\",\"video_content\":\"\",\"authors\":[{\"introduction\":\"中国科普研究所\",\"url\":\"\",\"nickname\":\"王大鹏\",\"avatar\":\"https://2-im.guokr.com/ddVa-TCvjjcfMAyF74vXi_SIm0Do-bqZNl5iEh9ZZMr_AAAAAAEAAEpQ.jpg\",\"ukey_author\":null}],\"replies_count\":12,\"is_author_external\":true,\"recommends_count\":0,\"title_hide\":\"道理讲了好多遍，为啥他就是听不进去？ \",\"date_modified\":\"2018-05-31T15:57:33.369940+08:00\",\"url\":\"http://www.guokr.com/article/442988/\",\"title\":\"道理讲了好多遍，为啥他就是听不进去？ \",\"small_image\":\"https://1-im.guokr.com/BKRFIIBHToe-2gqv9dV1UQ_vJ6lx0Dr9ksYbPM-OqO9KAQAAoAAAAEpQ.jpg\",\"summary\":\"从\\u201c庖丁解台词\\u201d谈谈科学传播\",\"ukey_author\":null,\"date_created\":\"2018-05-31T16:12:37+08:00\",\"resource_url\":\"http://apis.guokr.com/minisite/article/442988.json\"},{\"image\":\"\",\"is_replyable\":true,\"channels\":[{\"url\":\"http://www.guokr.com/scientific/channel/frontier/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"前沿\",\"key\":\"frontier\",\"articles_count\":4208}],\"channel_keys\":[\"frontier\"],\"preface\":\"\",\"id\":442987,\"subject\":{\"url\":\"http://www.guokr.com/scientific/subject/earth/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"地学\",\"key\":\"earth\",\"articles_count\":185},\"is_editor_recommend\":false,\"copyright\":\"owned_by_translate\",\"author\":{\"url\":\"https://www.sciencenews.org/author/laurel-hamers\",\"introduction\":\"Science News 杂志记者\",\"nickname\":\"Laurel Hamers\",\"avatar\":{\"small\":\"https://3-im.guokr.com/Gm9ehHJiIAHnAjvh0ywvAU_JdzDSq-NGuYoJRJfyQ8uSAwAAiAMAAFBO.png\",\"large\":\"https://3-im.guokr.com/Gm9ehHJiIAHnAjvh0ywvAU_JdzDSq-NGuYoJRJfyQ8uSAwAAiAMAAFBO.png\",\"normal\":\"https://3-im.guokr.com/Gm9ehHJiIAHnAjvh0ywvAU_JdzDSq-NGuYoJRJfyQ8uSAwAAiAMAAFBO.png\"}},\"image_description\":\"\",\"is_show_summary\":false,\"minisite_key\":null,\"image_info\":{\"url\":\"https://1-im.guokr.com/RsvsBgrZRagpKk010QhelyZMRW431KrnqaKVDEPGHIRKAQAAsQAAAEpQ.jpg\",\"width\":330,\"height\":177},\"subject_key\":\"earth\",\"minisite\":null,\"tags\":[\"小行星\",\"全球变暖\",\"天文\",\"恐龙\"],\"date_published\":\"2018-05-31T13:59:16+08:00\",\"video_content\":\"\",\"authors\":[{\"introduction\":\"Science News 杂志记者\",\"url\":\"https://www.sciencenews.org/author/laurel-hamers\",\"nickname\":\"Laurel Hamers\",\"avatar\":\"https://3-im.guokr.com/Gm9ehHJiIAHnAjvh0ywvAU_JdzDSq-NGuYoJRJfyQ8uSAwAAiAMAAFBO.png\",\"ukey_author\":null}],\"replies_count\":7,\"is_author_external\":true,\"recommends_count\":0,\"title_hide\":\"它不只灭掉了恐龙，还导致了随后10万年的全球变暖\",\"date_modified\":\"2018-05-31T13:59:10.703975+08:00\",\"url\":\"http://www.guokr.com/article/442987/\",\"title\":\"它不只灭掉了恐龙，还导致了随后10万年的全球变暖\",\"small_image\":\"https://1-im.guokr.com/RsvsBgrZRagpKk010QhelyZMRW431KrnqaKVDEPGHIRKAQAAsQAAAEpQ.jpg\",\"summary\":\"6600万年前撞击地球的那颗小行星，在随后的大约10万年里，让地球上的海洋温度上升了大约5℃。\",\"ukey_author\":null,\"date_created\":\"2018-05-31T13:59:16+08:00\",\"resource_url\":\"http://apis.guokr.com/minisite/article/442987.json\"},{\"image\":\"\",\"is_replyable\":true,\"channels\":[{\"url\":\"http://www.guokr.com/scientific/channel/hot/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"热点\",\"key\":\"hot\",\"articles_count\":1921}],\"channel_keys\":[\"hot\"],\"preface\":\"\",\"id\":442986,\"subject\":{\"url\":\"http://www.guokr.com/scientific/subject/others/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"其他\",\"key\":\"others\",\"articles_count\":291},\"is_editor_recommend\":false,\"copyright\":\"owned_by_guokr\",\"author\":{\"ukey\":\"2dxj2y\",\"is_title_authorized\":false,\"nickname\":\"vicko238\",\"master_category\":\"normal\",\"amended_reliability\":\"0\",\"is_exists\":true,\"title\":\"\",\"url\":\"http://www.guokr.com/i/0144331738/\",\"gender\":null,\"followers_count\":0,\"avatar\":{\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"},\"resource_url\":\"http://apis.guokr.com/community/user/2dxj2y.json\"},\"image_description\":\"\",\"is_show_summary\":false,\"minisite_key\":null,\"image_info\":{\"url\":\"https://1-im.guokr.com/xxz-r6j3SZuYnm2Ibg7Pk1wSPWf4HxdNHuyO-lOkhQVKAQAA6wAAAEpQ.jpg\",\"width\":330,\"height\":235},\"subject_key\":\"others\",\"minisite\":null,\"tags\":[\"考古\",\"火山\",\"历史\"],\"date_published\":\"2018-05-31T11:04:37+08:00\",\"video_content\":\"\",\"authors\":[{\"ukey\":\"2dxj2y\",\"is_title_authorized\":false,\"nickname\":\"vicko238\",\"master_category\":\"normal\",\"amended_reliability\":\"0\",\"is_exists\":true,\"title\":\"\",\"url\":\"http://www.guokr.com/i/0144331738/\",\"gender\":null,\"followers_count\":0,\"avatar\":{\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"},\"resource_url\":\"http://apis.guokr.com/community/user/2dxj2y.json\"}],\"replies_count\":22,\"is_author_external\":false,\"recommends_count\":0,\"title_hide\":\"庞贝古城新发现，一米巨石砸中逃难男子\",\"date_modified\":\"2018-05-31T11:09:13.675472+08:00\",\"url\":\"http://www.guokr.com/article/442986/\",\"title\":\"庞贝古城新发现，一米巨石砸中逃难男子\",\"small_image\":\"https://1-im.guokr.com/xxz-r6j3SZuYnm2Ibg7Pk1wSPWf4HxdNHuyO-lOkhQVKAQAA6wAAAEpQ.jpg\",\"summary\":\"现在他的头还不知所踪。\",\"ukey_author\":\"2dxj2y\",\"date_created\":\"2018-05-31T11:04:37+08:00\",\"resource_url\":\"http://apis.guokr.com/minisite/article/442986.json\"}]\n     * offset : 0\n     * total : 13396\n     */\n\n    private String now;\n    private boolean ok;\n    private int limit;\n    private int offset;\n    private int total;\n    private List<Result> result;\n\n    public String getNow() {\n        return now;\n    }\n\n    public void setNow(String now) {\n        this.now = now;\n    }\n\n    public boolean isOk() {\n        return ok;\n    }\n\n    public void setOk(boolean ok) {\n        this.ok = ok;\n    }\n\n    public int getLimit() {\n        return limit;\n    }\n\n    public void setLimit(int limit) {\n        this.limit = limit;\n    }\n\n    public int getOffset() {\n        return offset;\n    }\n\n    public void setOffset(int offset) {\n        this.offset = offset;\n    }\n\n    public int getTotal() {\n        return total;\n    }\n\n    public void setTotal(int total) {\n        this.total = total;\n    }\n\n    public List<Result> getResult() {\n        return result;\n    }\n\n    public void setResult(List<Result> result) {\n        this.result = result;\n    }\n\n    public static class Result {\n        /**\n         * image :\n         * is_replyable : true\n         * channels : []\n         * channel_keys : []\n         * preface :\n         * id : 443006\n         * subject : {\"url\":\"http://www.guokr.com/scientific/subject/medicine/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"医学\",\"key\":\"medicine\",\"articles_count\":1819}\n         * is_editor_recommend : false\n         * copyright : owned_by_guokr\n         * author : {\"ukey\":\"1jodqq\",\"is_title_authorized\":true,\"nickname\":\"飞刀断雨\",\"master_category\":\"personal\",\"amended_reliability\":\"0\",\"is_exists\":true,\"title\":\"临床医学专业，玄牝之门小组管理员\",\"url\":\"http://www.guokr.com/i/0093516434/\",\"gender\":\"female\",\"followers_count\":221,\"avatar\":{\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"},\"resource_url\":\"http://apis.guokr.com/community/user/1jodqq.json\"}\n         * image_description :\n         * is_show_summary : false\n         * minisite_key : health\n         * image_info : {\"url\":\"https://2-im.guokr.com/bfjAMXmfv0qwjQtnzLVOpJt-vu98su4VvVcHR_sUoh9KAQAA8AAAAEpQ.jpg\",\"width\":330,\"height\":240}\n         * subject_key : medicine\n         * minisite : {\"name\":\"健康朝九晚五\",\"url\":\"http://www.guokr.com/site/health/\",\"introduction\":\"每天的朝九晚五，上几篇健康小文，有趣、靠谱，还很给力\",\"key\":\"health\",\"date_created\":\"2010-10-20T16:20:43+08:00\",\"icon\":\"https://2-im.guokr.com/gDNaY8kFHIUnyDRLBlb1hWY3fwK9eAuV5icTVSuh7TNuAAAAWgAAAEpQ.jpg\"}\n         * tags : [\"转胎药\",\"转胎丸\"]\n         * date_published : 2018-06-08T14:26:01+08:00\n         * video_content :\n         * authors : [{\"ukey\":\"1jodqq\",\"is_title_authorized\":true,\"nickname\":\"飞刀断雨\",\"master_category\":\"personal\",\"amended_reliability\":\"0\",\"is_exists\":true,\"title\":\"临床医学专业，玄牝之门小组管理员\",\"url\":\"http://www.guokr.com/i/0093516434/\",\"gender\":\"female\",\"followers_count\":221,\"avatar\":{\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"},\"resource_url\":\"http://apis.guokr.com/community/user/1jodqq.json\"}]\n         * replies_count : 13\n         * is_author_external : false\n         * recommends_count : 0\n         * title_hide : “转胎丸”到底是个什么玩意？\n         * date_modified : 2018-06-08T14:59:40.953735+08:00\n         * url : http://www.guokr.com/article/443006/\n         * title : “转胎丸”到底是个什么玩意？\n         * small_image : https://2-im.guokr.com/bfjAMXmfv0qwjQtnzLVOpJt-vu98su4VvVcHR_sUoh9KAQAA8AAAAEpQ.jpg\n         * summary : 怀孕后吃几颗药，就能保证生男孩？所谓把女胎“转”成男胎的“转胎丸”，其实已经酿成了不少悲剧。\n         * ukey_author : 1jodqq\n         * date_created : 2018-06-08T14:26:01+08:00\n         * resource_url : http://apis.guokr.com/minisite/article/443006.json\n         */\n\n        private String image;\n        private boolean is_replyable;\n        private String preface;\n        private int id;\n        private Subject subject;\n        private boolean is_editor_recommend;\n        private String copyright;\n        private Author author;\n        private String image_description;\n        private boolean is_show_summary;\n        private String minisite_key;\n        private ImageInfo image_info;\n        private String subject_key;\n        private Minisite minisite;\n        private String date_published;\n        private String video_content;\n        private int replies_count;\n        private boolean is_author_external;\n        private int recommends_count;\n        private String title_hide;\n        private String date_modified;\n        private String url;\n        private String title;\n        private String small_image;\n        private String summary;\n        private String ukey_author;\n        private String date_created;\n        private String resource_url;\n        private List<?> channels;\n        private List<?> channel_keys;\n        private List<String> tags;\n        private List<Authors> authors;\n\n        public String getImage() {\n            return image;\n        }\n\n        public void setImage(String image) {\n            this.image = image;\n        }\n\n        public boolean isIs_replyable() {\n            return is_replyable;\n        }\n\n        public void setIs_replyable(boolean is_replyable) {\n            this.is_replyable = is_replyable;\n        }\n\n        public String getPreface() {\n            return preface;\n        }\n\n        public void setPreface(String preface) {\n            this.preface = preface;\n        }\n\n        public int getId() {\n            return id;\n        }\n\n        public void setId(int id) {\n            this.id = id;\n        }\n\n        public Subject getSubject() {\n            return subject;\n        }\n\n        public void setSubject(Subject subject) {\n            this.subject = subject;\n        }\n\n        public boolean isIs_editor_recommend() {\n            return is_editor_recommend;\n        }\n\n        public void setIs_editor_recommend(boolean is_editor_recommend) {\n            this.is_editor_recommend = is_editor_recommend;\n        }\n\n        public String getCopyright() {\n            return copyright;\n        }\n\n        public void setCopyright(String copyright) {\n            this.copyright = copyright;\n        }\n\n        public Author getAuthor() {\n            return author;\n        }\n\n        public void setAuthor(Author author) {\n            this.author = author;\n        }\n\n        public String getImage_description() {\n            return image_description;\n        }\n\n        public void setImage_description(String image_description) {\n            this.image_description = image_description;\n        }\n\n        public boolean isIs_show_summary() {\n            return is_show_summary;\n        }\n\n        public void setIs_show_summary(boolean is_show_summary) {\n            this.is_show_summary = is_show_summary;\n        }\n\n        public String getMinisite_key() {\n            return minisite_key;\n        }\n\n        public void setMinisite_key(String minisite_key) {\n            this.minisite_key = minisite_key;\n        }\n\n        public ImageInfo getImage_info() {\n            return image_info;\n        }\n\n        public void setImage_info(ImageInfo image_info) {\n            this.image_info = image_info;\n        }\n\n        public String getSubject_key() {\n            return subject_key;\n        }\n\n        public void setSubject_key(String subject_key) {\n            this.subject_key = subject_key;\n        }\n\n        public Minisite getMinisite() {\n            return minisite;\n        }\n\n        public void setMinisite(Minisite minisite) {\n            this.minisite = minisite;\n        }\n\n        public String getDate_published() {\n            return date_published;\n        }\n\n        public void setDate_published(String date_published) {\n            this.date_published = date_published;\n        }\n\n        public String getVideo_content() {\n            return video_content;\n        }\n\n        public void setVideo_content(String video_content) {\n            this.video_content = video_content;\n        }\n\n        public int getReplies_count() {\n            return replies_count;\n        }\n\n        public void setReplies_count(int replies_count) {\n            this.replies_count = replies_count;\n        }\n\n        public boolean isIs_author_external() {\n            return is_author_external;\n        }\n\n        public void setIs_author_external(boolean is_author_external) {\n            this.is_author_external = is_author_external;\n        }\n\n        public int getRecommends_count() {\n            return recommends_count;\n        }\n\n        public void setRecommends_count(int recommends_count) {\n            this.recommends_count = recommends_count;\n        }\n\n        public String getTitle_hide() {\n            return title_hide;\n        }\n\n        public void setTitle_hide(String title_hide) {\n            this.title_hide = title_hide;\n        }\n\n        public String getDate_modified() {\n            return date_modified;\n        }\n\n        public void setDate_modified(String date_modified) {\n            this.date_modified = date_modified;\n        }\n\n        public String getUrl() {\n            return url;\n        }\n\n        public void setUrl(String url) {\n            this.url = url;\n        }\n\n        public String getTitle() {\n            return title;\n        }\n\n        public void setTitle(String title) {\n            this.title = title;\n        }\n\n        public String getSmall_image() {\n            return small_image;\n        }\n\n        public void setSmall_image(String small_image) {\n            this.small_image = small_image;\n        }\n\n        public String getSummary() {\n            return summary;\n        }\n\n        public void setSummary(String summary) {\n            this.summary = summary;\n        }\n\n        public String getUkey_author() {\n            return ukey_author;\n        }\n\n        public void setUkey_author(String ukey_author) {\n            this.ukey_author = ukey_author;\n        }\n\n        public String getDate_created() {\n            return date_created;\n        }\n\n        public void setDate_created(String date_created) {\n            this.date_created = date_created;\n        }\n\n        public String getResource_url() {\n            return resource_url;\n        }\n\n        public void setResource_url(String resource_url) {\n            this.resource_url = resource_url;\n        }\n\n        public List<?> getChannels() {\n            return channels;\n        }\n\n        public void setChannels(List<?> channels) {\n            this.channels = channels;\n        }\n\n        public List<?> getChannel_keys() {\n            return channel_keys;\n        }\n\n        public void setChannel_keys(List<?> channel_keys) {\n            this.channel_keys = channel_keys;\n        }\n\n        public List<String> getTags() {\n            return tags;\n        }\n\n        public void setTags(List<String> tags) {\n            this.tags = tags;\n        }\n\n        public List<Authors> getAuthors() {\n            return authors;\n        }\n\n        public void setAuthors(List<Authors> authors) {\n            this.authors = authors;\n        }\n\n        public static class Subject {\n            /**\n             * url : http://www.guokr.com/scientific/subject/medicine/\n             * date_created : 2014-05-23T16:22:09.282129+08:00\n             * name : 医学\n             * key : medicine\n             * articles_count : 1819\n             */\n\n            private String url;\n            private String date_created;\n            private String name;\n            private String key;\n            private int articles_count;\n\n            public String getUrl() {\n                return url;\n            }\n\n            public void setUrl(String url) {\n                this.url = url;\n            }\n\n            public String getDate_created() {\n                return date_created;\n            }\n\n            public void setDate_created(String date_created) {\n                this.date_created = date_created;\n            }\n\n            public String getName() {\n                return name;\n            }\n\n            public void setName(String name) {\n                this.name = name;\n            }\n\n            public String getKey() {\n                return key;\n            }\n\n            public void setKey(String key) {\n                this.key = key;\n            }\n\n            public int getArticles_count() {\n                return articles_count;\n            }\n\n            public void setArticles_count(int articles_count) {\n                this.articles_count = articles_count;\n            }\n        }\n\n        public static class Author {\n            /**\n             * ukey : 1jodqq\n             * is_title_authorized : true\n             * nickname : 飞刀断雨\n             * master_category : personal\n             * amended_reliability : 0\n             * is_exists : true\n             * title : 临床医学专业，玄牝之门小组管理员\n             * url : http://www.guokr.com/i/0093516434/\n             * gender : female\n             * followers_count : 221\n             * avatar : {\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"}\n             * resource_url : http://apis.guokr.com/community/user/1jodqq.json\n             */\n\n            private String ukey;\n            private boolean is_title_authorized;\n            private String nickname;\n            private String master_category;\n            private String amended_reliability;\n            private boolean is_exists;\n            private String title;\n            private String url;\n            private String gender;\n            private int followers_count;\n            private Avatar avatar;\n            private String resource_url;\n\n            public String getUkey() {\n                return ukey;\n            }\n\n            public void setUkey(String ukey) {\n                this.ukey = ukey;\n            }\n\n            public boolean isIs_title_authorized() {\n                return is_title_authorized;\n            }\n\n            public void setIs_title_authorized(boolean is_title_authorized) {\n                this.is_title_authorized = is_title_authorized;\n            }\n\n            public String getNickname() {\n                return nickname;\n            }\n\n            public void setNickname(String nickname) {\n                this.nickname = nickname;\n            }\n\n            public String getMaster_category() {\n                return master_category;\n            }\n\n            public void setMaster_category(String master_category) {\n                this.master_category = master_category;\n            }\n\n            public String getAmended_reliability() {\n                return amended_reliability;\n            }\n\n            public void setAmended_reliability(String amended_reliability) {\n                this.amended_reliability = amended_reliability;\n            }\n\n            public boolean isIs_exists() {\n                return is_exists;\n            }\n\n            public void setIs_exists(boolean is_exists) {\n                this.is_exists = is_exists;\n            }\n\n            public String getTitle() {\n                return title;\n            }\n\n            public void setTitle(String title) {\n                this.title = title;\n            }\n\n            public String getUrl() {\n                return url;\n            }\n\n            public void setUrl(String url) {\n                this.url = url;\n            }\n\n            public String getGender() {\n                return gender;\n            }\n\n            public void setGender(String gender) {\n                this.gender = gender;\n            }\n\n            public int getFollowers_count() {\n                return followers_count;\n            }\n\n            public void setFollowers_count(int followers_count) {\n                this.followers_count = followers_count;\n            }\n\n            public Avatar getAvatar() {\n                return avatar;\n            }\n\n            public void setAvatar(Avatar avatar) {\n                this.avatar = avatar;\n            }\n\n            public String getResource_url() {\n                return resource_url;\n            }\n\n            public void setResource_url(String resource_url) {\n                this.resource_url = resource_url;\n            }\n\n            public static class Avatar {\n                /**\n                 * large : https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\n                 * small : https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\n                 * normal : https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\n                 */\n\n                private String large;\n                private String small;\n                private String normal;\n\n                public String getLarge() {\n                    return large;\n                }\n\n                public void setLarge(String large) {\n                    this.large = large;\n                }\n\n                public String getSmall() {\n                    return small;\n                }\n\n                public void setSmall(String small) {\n                    this.small = small;\n                }\n\n                public String getNormal() {\n                    return normal;\n                }\n\n                public void setNormal(String normal) {\n                    this.normal = normal;\n                }\n            }\n        }\n\n        public static class ImageInfo {\n            /**\n             * url : https://2-im.guokr.com/bfjAMXmfv0qwjQtnzLVOpJt-vu98su4VvVcHR_sUoh9KAQAA8AAAAEpQ.jpg\n             * width : 330\n             * height : 240\n             */\n\n            private String url;\n            private int width;\n            private int height;\n\n            public String getUrl() {\n                return url;\n            }\n\n            public void setUrl(String url) {\n                this.url = url;\n            }\n\n            public int getWidth() {\n                return width;\n            }\n\n            public void setWidth(int width) {\n                this.width = width;\n            }\n\n            public int getHeight() {\n                return height;\n            }\n\n            public void setHeight(int height) {\n                this.height = height;\n            }\n        }\n\n        public static class Minisite {\n            /**\n             * name : 健康朝九晚五\n             * url : http://www.guokr.com/site/health/\n             * introduction : 每天的朝九晚五，上几篇健康小文，有趣、靠谱，还很给力\n             * key : health\n             * date_created : 2010-10-20T16:20:43+08:00\n             * icon : https://2-im.guokr.com/gDNaY8kFHIUnyDRLBlb1hWY3fwK9eAuV5icTVSuh7TNuAAAAWgAAAEpQ.jpg\n             */\n\n            private String name;\n            private String url;\n            private String introduction;\n            private String key;\n            private String date_created;\n            private String icon;\n\n            public String getName() {\n                return name;\n            }\n\n            public void setName(String name) {\n                this.name = name;\n            }\n\n            public String getUrl() {\n                return url;\n            }\n\n            public void setUrl(String url) {\n                this.url = url;\n            }\n\n            public String getIntroduction() {\n                return introduction;\n            }\n\n            public void setIntroduction(String introduction) {\n                this.introduction = introduction;\n            }\n\n            public String getKey() {\n                return key;\n            }\n\n            public void setKey(String key) {\n                this.key = key;\n            }\n\n            public String getDate_created() {\n                return date_created;\n            }\n\n            public void setDate_created(String date_created) {\n                this.date_created = date_created;\n            }\n\n            public String getIcon() {\n                return icon;\n            }\n\n            public void setIcon(String icon) {\n                this.icon = icon;\n            }\n        }\n\n        public static class Authors {\n            /**\n             * ukey : 1jodqq\n             * is_title_authorized : true\n             * nickname : 飞刀断雨\n             * master_category : personal\n             * amended_reliability : 0\n             * is_exists : true\n             * title : 临床医学专业，玄牝之门小组管理员\n             * url : http://www.guokr.com/i/0093516434/\n             * gender : female\n             * followers_count : 221\n             * avatar : {\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"}\n             * resource_url : http://apis.guokr.com/community/user/1jodqq.json\n             */\n\n            private String ukey;\n            private boolean is_title_authorized;\n            private String nickname;\n            private String master_category;\n            private String amended_reliability;\n            private boolean is_exists;\n            private String title;\n            private String url;\n            private String gender;\n            private int followers_count;\n            private Object avatar;\n            private String resource_url;\n\n            public String getUkey() {\n                return ukey;\n            }\n\n            public void setUkey(String ukey) {\n                this.ukey = ukey;\n            }\n\n            public boolean isIs_title_authorized() {\n                return is_title_authorized;\n            }\n\n            public void setIs_title_authorized(boolean is_title_authorized) {\n                this.is_title_authorized = is_title_authorized;\n            }\n\n            public String getNickname() {\n                return nickname;\n            }\n\n            public void setNickname(String nickname) {\n                this.nickname = nickname;\n            }\n\n            public String getMaster_category() {\n                return master_category;\n            }\n\n            public void setMaster_category(String master_category) {\n                this.master_category = master_category;\n            }\n\n            public String getAmended_reliability() {\n                return amended_reliability;\n            }\n\n            public void setAmended_reliability(String amended_reliability) {\n                this.amended_reliability = amended_reliability;\n            }\n\n            public boolean isIs_exists() {\n                return is_exists;\n            }\n\n            public void setIs_exists(boolean is_exists) {\n                this.is_exists = is_exists;\n            }\n\n            public String getTitle() {\n                return title;\n            }\n\n            public void setTitle(String title) {\n                this.title = title;\n            }\n\n            public String getUrl() {\n                return url;\n            }\n\n            public void setUrl(String url) {\n                this.url = url;\n            }\n\n            public String getGender() {\n                return gender;\n            }\n\n            public void setGender(String gender) {\n                this.gender = gender;\n            }\n\n            public int getFollowers_count() {\n                return followers_count;\n            }\n\n            public void setFollowers_count(int followers_count) {\n                this.followers_count = followers_count;\n            }\n\n            public Object getAvatar() {\n                return avatar;\n            }\n\n            public void setAvatar(Object avatar) {\n                this.avatar = avatar;\n            }\n\n            public String getResource_url() {\n                return resource_url;\n            }\n\n            public void setResource_url(String resource_url) {\n                this.resource_url = resource_url;\n            }\n\n            public static class AvatarX {\n                /**\n                 * large : https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\n                 * small : https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\n                 * normal : https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\n                 */\n\n                private String large;\n                private String small;\n                private String normal;\n\n                public String getLarge() {\n                    return large;\n                }\n\n                public void setLarge(String large) {\n                    this.large = large;\n                }\n\n                public String getSmall() {\n                    return small;\n                }\n\n                public void setSmall(String small) {\n                    this.small = small;\n                }\n\n                public String getNormal() {\n                    return normal;\n                }\n\n                public void setNormal(String normal) {\n                    this.normal = normal;\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "guokr/src/main/java/me/shouheng/guokr/model/data/GuokrNewsContent.java",
    "content": "package me.shouheng.guokr.model.data;\n\nimport java.util.List;\n\n/**\n * @author shouh\n * @version $Id: GuokrNewsContent, v 0.1 2018/6/10 19:07 shouh Exp$\n */\npublic class GuokrNewsContent {\n\n    /**\n     * now : 2018-06-10T19:07:18.169461+08:00\n     * ok : true\n     * result : {\"image\":\"\",\"is_replyable\":true,\"channels\":[],\"channel_keys\":[],\"preface\":\"\",\"id\":443006,\"subject\":{\"url\":\"http://www.guokr.com/scientific/subject/medicine/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"医学\",\"key\":\"medicine\",\"articles_count\":1819},\"is_editor_recommend\":false,\"copyright\":\"owned_by_guokr\",\"author\":{\"ukey\":\"1jodqq\",\"is_title_authorized\":true,\"nickname\":\"飞刀断雨\",\"master_category\":\"personal\",\"amended_reliability\":\"0\",\"is_exists\":true,\"title\":\"临床医学专业，玄牝之门小组管理员\",\"url\":\"http://www.guokr.com/i/0093516434/\",\"gender\":\"female\",\"followers_count\":221,\"avatar\":{\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"},\"resource_url\":\"http://apis.guokr.com/community/user/1jodqq.json\"},\"image_description\":\"\",\"content\":\"<div><p>号称能\\u201c包生男\\u201d的药物，从前一直有，以后也不会消失。这些药物又可以分为两大类。第一类谋财不害命，宣称无效退款，发货就发几颗维生素丸或者糯米粉丸，虽然退款率高达一半，但还有另一半能稳稳白赚。比第一类更可怕的，是谋财又害命的第二类药物，它们常常顶着\\u201c转胎药\\u201d的名字，干着致人流产、畸形、生病的勾当。<\\/p>\\r\\n\\r\\n<h2>\\u201c转胎药\\u201d，其实是大剂量雄激素<\\/h2>\\r\\n\\r\\n<p>随便搜一下\\u201c转胎药\\u201d，就会看到许多不幸的新闻\\u2014\\u2014<\\/p>\\r\\n\\r\\n<p>2012年3月，河南驻马店，女子因服用转胎丸生下双性儿。<\\/p>\\r\\n\\r\\n<p><img src=\\\"https://1-im.guokr.com/8Trde1eaoQAx9DWXIX1ESc8cc8H6rzLsjPjJhcOn3dKjAwAAxgEAAFBO.png?imageView2/1/w/555/h/270\\\"><\\/p>\\r\\n\\r\\n<p>2017年8月，江苏连云港，家长带着一名现已四岁的双性儿来求医，询问病史后发现，其母亲怀孕时服用过\\u201c转胎药\\u201d。<\\/p>\\r\\n\\r\\n<p><img src=\\\"https://2-im.guokr.com/t6RpvdziERn3fKIJVWto5249Vm0MO6BFBfMH0rozX5znAwAAGgEAAFBO.png?imageView2/1/w/555/h/156\\\"><\\/p>\\r\\n\\r\\n<p>这些新闻里的\\u201c双性人\\u201d，医学上叫做女性假两性畸形。这种畸形，是因为在胚胎发育期间接触了过多的雄激素。<\\/p>\\r\\n\\r\\n<p>雄激素从何而来？常见原因有两种，一种是胎儿自身产生了过多的雄激素，如患有先天性肾上腺皮质增生症的胎儿；另一种就是孕妇给了胎儿过多的雄激素，比如孕妇患有多囊卵巢等导致雄激素增高的疾病，又比如，孕妇在孕期服用了雄激素类药物<sup>[1]<\\/sup>。<\\/p>\\r\\n\\r\\n<p>新闻里孕妇吃下的\\u201c转胎药\\u201d，正是雄激素的来源，也是造成这些孩子畸形的罪魁祸首。而且这些悲剧绝不是孤例。1997年11月~1999年12月，安徽省淮南矿工二院曾陆续收治了九名来自同一村镇的假两性畸形患者，她们的母亲均在孕2月左右服用了名为\\u201c转胎药\\u201d的甲基睾丸素<sup>[2]<\\/sup>。<\\/p>\\r\\n\\r\\n<p>甲基睾丸素是雄激素类药，会导致女性胎儿生殖器官发育异常。就算在大剂量雄激素作用下变得看似男性，性染色体还是女孩，结果就会变成女性假两性畸形。<\\/p>\\r\\n\\r\\n<p>如果没有雄激素的干扰，她们本该发育成正常女性，故而她们卵巢、子宫、阴道都有。然而过多的雄激素让外生殖器男性化，男性化的严重程度取决于接触雄激素的时机和量。如果服药较晚，胎儿泌尿生殖系统已经发育完成，那么可能仅表现为阴蒂粗大。如果孕早期就服药，泌尿生殖系统还没有发育完成，则可能会有阴茎形成，阴唇肥大融合如同没有睾丸的阴囊，覆盖尿道和阴道口，还可能会伴有泌尿系统畸形。<\\/p>\\r\\n\\r\\n<p>比起胎儿本身原因导致的男性化畸形，服药导致的畸形症状一般都相对较轻，而且因为脱离母体后就不再处于高雄激素环境，畸形症状在出生后不会进一步加剧，有的人还能正常月经来潮甚至正常生育<sup>[3]<\\/sup>。但是先天性畸形毕竟已经造成，除了男性化外观带来的心理压力外，许多人还伴有多毛症、经血不能正常排出、血尿等问题<sup>[4]<\\/sup>。<\\/p>\\r\\n\\r\\n<p>如果要治疗假两性畸形，矫正手术最佳的年龄是2~4岁，过早有病情复发、需要二次手术的风险，过晚又会影响患者的精神心理<sup>[5]<\\/sup>。然而因为家中对此病认识的不足，患者就医时往往已错过最佳手术时机。另外，阴蒂成形手术还有导致患者性敏感度降低的风险<sup>[6]<\\/sup>，很多孩子手术后也会因为社会性别和生理性别不相符，心理上发生严重冲突<sup>[7]<\\/sup>。<\\/p>\\r\\n\\r\\n<p>也不要以为雄激素只会伤害女胎，男胎一样会出问题。转胎药完全可能造成流产。吃完转胎药还能平安出生的，都是命大。这是因为甲基睾丸素还有抗生育的作用，可降低蜕膜组织雌激素受体含量，使蜕膜和绒毛组织退化变性<sup>[8]<\\/sup>，简而言之，这种药能切断胚胎和母体的联系，和药物流产是一个道理。临床上也常有将甲基睾丸素和药物流产的药物协同使用，以加强药流效果的。<\\/p>\\r\\n\\r\\n<h2>安全又有效的\\u201c转胎药\\u201d，根本不可能存在<\\/h2>\\r\\n\\r\\n<p>肚子里的孩子是男还是女，受精卵形成的那一刻就已经决定了。<\\/p>\\r\\n\\r\\n<p>决定生物性状的，是遗传物质，所以鸭蛋里不会孵出熊猫，人类也不会生出龙宝宝。女性的性染色体是XX组合，男性的性染色体是XY组合。想强行把胎儿的X变成Y，是绝对办不到的。<\\/p>\\r\\n\\r\\n<p class=\\\"img-caption\\\"><img src=\\\"https://3-im.guokr.com/0lSlGxgGIQkSQVA_Ja0U3Gxo0tPNIxuBCIXElrbkhpEXBAAAagMAAFBO.png?imageView2/1/w/555/h/463\\\">看看X染色体和Y染色体的长相差多少吧。图片来源：Jonathan Bailey, NHGRI<\\/p>\\r\\n\\r\\n<p>服下\\u201c转胎药\\u201d的那一刻，往往怀孕已经好几个月，受精卵不知分裂了多少次，这时候要把胚胎的X染色体变成Y染色体，这个操作的难度有多大呢？<\\/p>\\r\\n\\r\\n<p>首先，得把所有胚胎细胞的染色体都改掉，一个细胞都不可以漏掉。否则万一用来分化成丁丁蛋蛋的那部分细胞正好没改，不就白费了这番辛苦？<\\/p>\\r\\n\\r\\n<p>其次，人类的46条染色体各有不同、不可或缺，改的时候得从46条染色体里精准地找出其中一条X染色体，不能误伤另一条X染色体和其它常染色体，更不能把两个X染色体全变成Y染色体\\u2014\\u2014这样的胚胎缺少X染色体上的发育所必须的关键基因，根本活不下来。得是什么样的\\u201c转胎药\\u201d才能有这么好的眼神呢？<\\/p>\\r\\n\\r\\n<p>最后也是最重要的一点，染色体不是任你搓圆揉扁的橡皮泥。染色体中有海量的遗传信息，Y染色体上更是有X染色体上所没有的性别决定基因SRY（Sex-Determining Region Y）和其它一些睾丸刺激因子、生精相关基因等，只有这些基因相互作用，最后才能刺激男性的生殖器官生成，任何一个环节出现异常，都会导致发育异常、不育等等问题<sup>[9]<\\/sup>。想吃个药就把基因\\u201c改头换面\\u201d？怎么可能。退一万步说，要真有这么强大的药，你不怕它把整个基因组修改得面目全非，造成各种畸形乃至癌症吗？<\\/p>\\r\\n\\r\\n<p>如果吃转胎药只是一个像\\u201c西红柿炒蛋里要不要加糖\\u201d一样无可无不可的问题，我们大可以不去深究，各人随意。但这是药啊！医生和药师给孕妇开药的时候，在了解药物成分和用药风险的基础上，尚且要权衡利弊、斟酌用量，怎么你们随便搞一个来历不明的药，就敢让孕妇吃呢？<\\/p>\\r\\n\\r\\n<p>写这篇文章的过程中，我的心情一直非常沉重，调整了几次才慢慢组织出来。一方面，我心疼那些因为父母家人的无知而遭受无妄之灾，无端承受畸形痛苦的孩子们；另一方面，我也总会想起那些被堕胎的、被溺死的女婴。说到底，许多悲剧都是缘于重男轻女的思想。对男孩的偏好，造成了中国畸高的出生性别比和明显偏离正常的女孩死亡水平。即使我写了此文，也只是给重男轻女的人指明此路不通，而他们还会有更多层出不穷的办法，阻止女婴在这个世界降临和生存。每思及此，心灰意冷。 （编辑：游识猷） <\\/p>\\r\\n\\r\\n<h2 class=\\\"references\\\">参考资料<\\/h2>\\r\\n\\r\\n<ol class=\\\"reference-item\\\"><li>Galani A，Kitsiou\\u2014Tzeli S，Sofokleous C，et a1．Androgeninsensitivity syndrome：clinical features and molecular defects[J]．Hormones(Athens)， 2008，7(3)：217\\u2014229．<\\/li>\\r\\n\\t<li>李莉.孕早期服甲基睾丸素致子代女性假两性畸形9例[J].中国煤炭工业医学杂志,2001,(6):423. DOI:10.3969/j.issn.1007-9564.2001.06.010.<\\/li>\\r\\n\\t<li>谢幸, 苟文丽. 妇产科学第八版[M]. 北京市:人民卫生出版社, 2013.<\\/li>\\r\\n\\t<li>李全荣,林蓓,伊喜苓, 等.342例女性假两性畸形的荟萃分析[J].中国医科大学学报,2010,(1):64-66,70.<\\/li>\\r\\n\\t<li>LiBU，Balint JP．Cyclicvomiting syndrome：evolutionin our understanding of a brain\\u2014gutdisorder[J]．Adv Pedimr，2000，47(2)： 117一160．<\\/li>\\r\\n\\t<li>ChepyMa P，Svoboda RP，Olden KW．Treatment of cyclic vomiting syndrome[J]．Curt Treat Options Gastroenteml，2007，10(4)：273- 282．<\\/li>\\r\\n\\t<li>关琳瑶,刘长松.女性假两性畸形患者的心理分析及干预[J].中国美容医学,2012,(3):508-509. DOI:10.3969/j.issn.1008-6455.2012.03.072.<\\/li>\\r\\n\\t<li>彭飞红.甲基睾丸素用于药物流产的临床应用[J].深圳中西医结合杂志,2001,(3):171-172. DOI:10.3969/j.issn.1007-0893.2001.03.024.<\\/li>\\r\\n\\t<li>段晓刚,张红国.人类Y染色体研究进展[J].中国优生与遗传杂志,2006,(1):1-3. DOI:10.3969/j.issn.1006-9534.2006.01.001.<\\/li>\\r\\n<\\/ol><\\/div>\",\"is_show_summary\":false,\"minisite_key\":\"health\",\"image_info\":{\"url\":\"https://2-im.guokr.com/bfjAMXmfv0qwjQtnzLVOpJt-vu98su4VvVcHR_sUoh9KAQAA8AAAAEpQ.jpg\",\"width\":330,\"height\":240},\"subject_key\":\"medicine\",\"minisite\":{\"name\":\"健康朝九晚五\",\"url\":\"http://www.guokr.com/site/health/\",\"introduction\":\"每天的朝九晚五，上几篇健康小文，有趣、靠谱，还很给力\",\"key\":\"health\",\"date_created\":\"2010-10-20T16:20:43+08:00\",\"icon\":\"https://2-im.guokr.com/gDNaY8kFHIUnyDRLBlb1hWY3fwK9eAuV5icTVSuh7TNuAAAAWgAAAEpQ.jpg\"},\"tags\":[\"转胎药\",\"转胎丸\"],\"date_published\":\"2018-06-08T14:26:01+08:00\",\"video_content\":\"\",\"authors\":[{\"ukey\":\"1jodqq\",\"is_title_authorized\":true,\"nickname\":\"飞刀断雨\",\"master_category\":\"personal\",\"amended_reliability\":\"0\",\"is_exists\":true,\"title\":\"临床医学专业，玄牝之门小组管理员\",\"url\":\"http://www.guokr.com/i/0093516434/\",\"gender\":\"female\",\"followers_count\":221,\"avatar\":{\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"},\"resource_url\":\"http://apis.guokr.com/community/user/1jodqq.json\"}],\"replies_count\":14,\"is_author_external\":false,\"recommends_count\":0,\"title_hide\":\"\\u201c转胎丸\\u201d到底是个什么玩意？\",\"date_modified\":\"2018-06-08T14:59:40.953735+08:00\",\"url\":\"http://www.guokr.com/article/443006/\",\"title\":\"\\u201c转胎丸\\u201d到底是个什么玩意？\",\"small_image\":\"https://2-im.guokr.com/bfjAMXmfv0qwjQtnzLVOpJt-vu98su4VvVcHR_sUoh9KAQAA8AAAAEpQ.jpg\",\"summary\":\"怀孕后吃几颗药，就能保证生男孩？所谓把女胎\\u201c转\\u201d成男胎的\\u201c转胎丸\\u201d，其实已经酿成了不少悲剧。\",\"ukey_author\":\"1jodqq\",\"date_created\":\"2018-06-08T14:26:01+08:00\",\"resource_url\":\"http://apis.guokr.com/minisite/article/443006.json\"}\n     */\n\n    private String now;\n    private boolean ok;\n    private Result result;\n\n    public String getNow() {\n        return now;\n    }\n\n    public void setNow(String now) {\n        this.now = now;\n    }\n\n    public boolean isOk() {\n        return ok;\n    }\n\n    public void setOk(boolean ok) {\n        this.ok = ok;\n    }\n\n    public Result getResult() {\n        return result;\n    }\n\n    public void setResult(Result result) {\n        this.result = result;\n    }\n\n    public static class Result {\n        /**\n         * image :\n         * is_replyable : true\n         * channels : []\n         * channel_keys : []\n         * preface :\n         * id : 443006\n         * subject : {\"url\":\"http://www.guokr.com/scientific/subject/medicine/\",\"date_created\":\"2014-05-23T16:22:09.282129+08:00\",\"name\":\"医学\",\"key\":\"medicine\",\"articles_count\":1819}\n         * is_editor_recommend : false\n         * copyright : owned_by_guokr\n         * author : {\"ukey\":\"1jodqq\",\"is_title_authorized\":true,\"nickname\":\"飞刀断雨\",\"master_category\":\"personal\",\"amended_reliability\":\"0\",\"is_exists\":true,\"title\":\"临床医学专业，玄牝之门小组管理员\",\"url\":\"http://www.guokr.com/i/0093516434/\",\"gender\":\"female\",\"followers_count\":221,\"avatar\":{\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"},\"resource_url\":\"http://apis.guokr.com/community/user/1jodqq.json\"}\n         * image_description :\n         * content : <div><p>号称能“包生男”的药物，从前一直有，以后也不会消失。这些药物又可以分为两大类。第一类谋财不害命，宣称无效退款，发货就发几颗维生素丸或者糯米粉丸，虽然退款率高达一半，但还有另一半能稳稳白赚。比第一类更可怕的，是谋财又害命的第二类药物，它们常常顶着“转胎药”的名字，干着致人流产、畸形、生病的勾当。</p>\n\n         <h2>“转胎药”，其实是大剂量雄激素</h2>\n\n         <p>随便搜一下“转胎药”，就会看到许多不幸的新闻——</p>\n\n         <p>2012年3月，河南驻马店，女子因服用转胎丸生下双性儿。</p>\n\n         <p><img src=\"https://1-im.guokr.com/8Trde1eaoQAx9DWXIX1ESc8cc8H6rzLsjPjJhcOn3dKjAwAAxgEAAFBO.png?imageView2/1/w/555/h/270\"></p>\n\n         <p>2017年8月，江苏连云港，家长带着一名现已四岁的双性儿来求医，询问病史后发现，其母亲怀孕时服用过“转胎药”。</p>\n\n         <p><img src=\"https://2-im.guokr.com/t6RpvdziERn3fKIJVWto5249Vm0MO6BFBfMH0rozX5znAwAAGgEAAFBO.png?imageView2/1/w/555/h/156\"></p>\n\n         <p>这些新闻里的“双性人”，医学上叫做女性假两性畸形。这种畸形，是因为在胚胎发育期间接触了过多的雄激素。</p>\n\n         <p>雄激素从何而来？常见原因有两种，一种是胎儿自身产生了过多的雄激素，如患有先天性肾上腺皮质增生症的胎儿；另一种就是孕妇给了胎儿过多的雄激素，比如孕妇患有多囊卵巢等导致雄激素增高的疾病，又比如，孕妇在孕期服用了雄激素类药物<sup>[1]</sup>。</p>\n\n         <p>新闻里孕妇吃下的“转胎药”，正是雄激素的来源，也是造成这些孩子畸形的罪魁祸首。而且这些悲剧绝不是孤例。1997年11月~1999年12月，安徽省淮南矿工二院曾陆续收治了九名来自同一村镇的假两性畸形患者，她们的母亲均在孕2月左右服用了名为“转胎药”的甲基睾丸素<sup>[2]</sup>。</p>\n\n         <p>甲基睾丸素是雄激素类药，会导致女性胎儿生殖器官发育异常。就算在大剂量雄激素作用下变得看似男性，性染色体还是女孩，结果就会变成女性假两性畸形。</p>\n\n         <p>如果没有雄激素的干扰，她们本该发育成正常女性，故而她们卵巢、子宫、阴道都有。然而过多的雄激素让外生殖器男性化，男性化的严重程度取决于接触雄激素的时机和量。如果服药较晚，胎儿泌尿生殖系统已经发育完成，那么可能仅表现为阴蒂粗大。如果孕早期就服药，泌尿生殖系统还没有发育完成，则可能会有阴茎形成，阴唇肥大融合如同没有睾丸的阴囊，覆盖尿道和阴道口，还可能会伴有泌尿系统畸形。</p>\n\n         <p>比起胎儿本身原因导致的男性化畸形，服药导致的畸形症状一般都相对较轻，而且因为脱离母体后就不再处于高雄激素环境，畸形症状在出生后不会进一步加剧，有的人还能正常月经来潮甚至正常生育<sup>[3]</sup>。但是先天性畸形毕竟已经造成，除了男性化外观带来的心理压力外，许多人还伴有多毛症、经血不能正常排出、血尿等问题<sup>[4]</sup>。</p>\n\n         <p>如果要治疗假两性畸形，矫正手术最佳的年龄是2~4岁，过早有病情复发、需要二次手术的风险，过晚又会影响患者的精神心理<sup>[5]</sup>。然而因为家中对此病认识的不足，患者就医时往往已错过最佳手术时机。另外，阴蒂成形手术还有导致患者性敏感度降低的风险<sup>[6]</sup>，很多孩子手术后也会因为社会性别和生理性别不相符，心理上发生严重冲突<sup>[7]</sup>。</p>\n\n         <p>也不要以为雄激素只会伤害女胎，男胎一样会出问题。转胎药完全可能造成流产。吃完转胎药还能平安出生的，都是命大。这是因为甲基睾丸素还有抗生育的作用，可降低蜕膜组织雌激素受体含量，使蜕膜和绒毛组织退化变性<sup>[8]</sup>，简而言之，这种药能切断胚胎和母体的联系，和药物流产是一个道理。临床上也常有将甲基睾丸素和药物流产的药物协同使用，以加强药流效果的。</p>\n\n         <h2>安全又有效的“转胎药”，根本不可能存在</h2>\n\n         <p>肚子里的孩子是男还是女，受精卵形成的那一刻就已经决定了。</p>\n\n         <p>决定生物性状的，是遗传物质，所以鸭蛋里不会孵出熊猫，人类也不会生出龙宝宝。女性的性染色体是XX组合，男性的性染色体是XY组合。想强行把胎儿的X变成Y，是绝对办不到的。</p>\n\n         <p class=\"img-caption\"><img src=\"https://3-im.guokr.com/0lSlGxgGIQkSQVA_Ja0U3Gxo0tPNIxuBCIXElrbkhpEXBAAAagMAAFBO.png?imageView2/1/w/555/h/463\">看看X染色体和Y染色体的长相差多少吧。图片来源：Jonathan Bailey, NHGRI</p>\n\n         <p>服下“转胎药”的那一刻，往往怀孕已经好几个月，受精卵不知分裂了多少次，这时候要把胚胎的X染色体变成Y染色体，这个操作的难度有多大呢？</p>\n\n         <p>首先，得把所有胚胎细胞的染色体都改掉，一个细胞都不可以漏掉。否则万一用来分化成丁丁蛋蛋的那部分细胞正好没改，不就白费了这番辛苦？</p>\n\n         <p>其次，人类的46条染色体各有不同、不可或缺，改的时候得从46条染色体里精准地找出其中一条X染色体，不能误伤另一条X染色体和其它常染色体，更不能把两个X染色体全变成Y染色体——这样的胚胎缺少X染色体上的发育所必须的关键基因，根本活不下来。得是什么样的“转胎药”才能有这么好的眼神呢？</p>\n\n         <p>最后也是最重要的一点，染色体不是任你搓圆揉扁的橡皮泥。染色体中有海量的遗传信息，Y染色体上更是有X染色体上所没有的性别决定基因SRY（Sex-Determining Region Y）和其它一些睾丸刺激因子、生精相关基因等，只有这些基因相互作用，最后才能刺激男性的生殖器官生成，任何一个环节出现异常，都会导致发育异常、不育等等问题<sup>[9]</sup>。想吃个药就把基因“改头换面”？怎么可能。退一万步说，要真有这么强大的药，你不怕它把整个基因组修改得面目全非，造成各种畸形乃至癌症吗？</p>\n\n         <p>如果吃转胎药只是一个像“西红柿炒蛋里要不要加糖”一样无可无不可的问题，我们大可以不去深究，各人随意。但这是药啊！医生和药师给孕妇开药的时候，在了解药物成分和用药风险的基础上，尚且要权衡利弊、斟酌用量，怎么你们随便搞一个来历不明的药，就敢让孕妇吃呢？</p>\n\n         <p>写这篇文章的过程中，我的心情一直非常沉重，调整了几次才慢慢组织出来。一方面，我心疼那些因为父母家人的无知而遭受无妄之灾，无端承受畸形痛苦的孩子们；另一方面，我也总会想起那些被堕胎的、被溺死的女婴。说到底，许多悲剧都是缘于重男轻女的思想。对男孩的偏好，造成了中国畸高的出生性别比和明显偏离正常的女孩死亡水平。即使我写了此文，也只是给重男轻女的人指明此路不通，而他们还会有更多层出不穷的办法，阻止女婴在这个世界降临和生存。每思及此，心灰意冷。 （编辑：游识猷） </p>\n\n         <h2 class=\"references\">参考资料</h2>\n\n         <ol class=\"reference-item\"><li>Galani A，Kitsiou—Tzeli S，Sofokleous C，et a1．Androgeninsensitivity syndrome：clinical features and molecular defects[J]．Hormones(Athens)， 2008，7(3)：217—229．</li>\n         <li>李莉.孕早期服甲基睾丸素致子代女性假两性畸形9例[J].中国煤炭工业医学杂志,2001,(6):423. DOI:10.3969/j.issn.1007-9564.2001.06.010.</li>\n         <li>谢幸, 苟文丽. 妇产科学第八版[M]. 北京市:人民卫生出版社, 2013.</li>\n         <li>李全荣,林蓓,伊喜苓, 等.342例女性假两性畸形的荟萃分析[J].中国医科大学学报,2010,(1):64-66,70.</li>\n         <li>LiBU，Balint JP．Cyclicvomiting syndrome：evolutionin our understanding of a brain—gutdisorder[J]．Adv Pedimr，2000，47(2)： 117一160．</li>\n         <li>ChepyMa P，Svoboda RP，Olden KW．Treatment of cyclic vomiting syndrome[J]．Curt Treat Options Gastroenteml，2007，10(4)：273- 282．</li>\n         <li>关琳瑶,刘长松.女性假两性畸形患者的心理分析及干预[J].中国美容医学,2012,(3):508-509. DOI:10.3969/j.issn.1008-6455.2012.03.072.</li>\n         <li>彭飞红.甲基睾丸素用于药物流产的临床应用[J].深圳中西医结合杂志,2001,(3):171-172. DOI:10.3969/j.issn.1007-0893.2001.03.024.</li>\n         <li>段晓刚,张红国.人类Y染色体研究进展[J].中国优生与遗传杂志,2006,(1):1-3. DOI:10.3969/j.issn.1006-9534.2006.01.001.</li>\n         </ol></div>\n         * is_show_summary : false\n         * minisite_key : health\n         * image_info : {\"url\":\"https://2-im.guokr.com/bfjAMXmfv0qwjQtnzLVOpJt-vu98su4VvVcHR_sUoh9KAQAA8AAAAEpQ.jpg\",\"width\":330,\"height\":240}\n         * subject_key : medicine\n         * minisite : {\"name\":\"健康朝九晚五\",\"url\":\"http://www.guokr.com/site/health/\",\"introduction\":\"每天的朝九晚五，上几篇健康小文，有趣、靠谱，还很给力\",\"key\":\"health\",\"date_created\":\"2010-10-20T16:20:43+08:00\",\"icon\":\"https://2-im.guokr.com/gDNaY8kFHIUnyDRLBlb1hWY3fwK9eAuV5icTVSuh7TNuAAAAWgAAAEpQ.jpg\"}\n         * tags : [\"转胎药\",\"转胎丸\"]\n         * date_published : 2018-06-08T14:26:01+08:00\n         * video_content :\n         * authors : [{\"ukey\":\"1jodqq\",\"is_title_authorized\":true,\"nickname\":\"飞刀断雨\",\"master_category\":\"personal\",\"amended_reliability\":\"0\",\"is_exists\":true,\"title\":\"临床医学专业，玄牝之门小组管理员\",\"url\":\"http://www.guokr.com/i/0093516434/\",\"gender\":\"female\",\"followers_count\":221,\"avatar\":{\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"},\"resource_url\":\"http://apis.guokr.com/community/user/1jodqq.json\"}]\n         * replies_count : 14\n         * is_author_external : false\n         * recommends_count : 0\n         * title_hide : “转胎丸”到底是个什么玩意？\n         * date_modified : 2018-06-08T14:59:40.953735+08:00\n         * url : http://www.guokr.com/article/443006/\n         * title : “转胎丸”到底是个什么玩意？\n         * small_image : https://2-im.guokr.com/bfjAMXmfv0qwjQtnzLVOpJt-vu98su4VvVcHR_sUoh9KAQAA8AAAAEpQ.jpg\n         * summary : 怀孕后吃几颗药，就能保证生男孩？所谓把女胎“转”成男胎的“转胎丸”，其实已经酿成了不少悲剧。\n         * ukey_author : 1jodqq\n         * date_created : 2018-06-08T14:26:01+08:00\n         * resource_url : http://apis.guokr.com/minisite/article/443006.json\n         */\n\n        private String image;\n        private boolean is_replyable;\n        private String preface;\n        private int id;\n        private Subject subject;\n        private boolean is_editor_recommend;\n        private String copyright;\n        private Author author;\n        private String image_description;\n        private String content;\n        private boolean is_show_summary;\n        private String minisite_key;\n        private ImageInfo image_info;\n        private String subject_key;\n        private Minisite minisite;\n        private String date_published;\n        private String video_content;\n        private int replies_count;\n        private boolean is_author_external;\n        private int recommends_count;\n        private String title_hide;\n        private String date_modified;\n        private String url;\n        private String title;\n        private String small_image;\n        private String summary;\n        private String ukey_author;\n        private String date_created;\n        private String resource_url;\n        private List<?> channels;\n        private List<?> channel_keys;\n        private List<String> tags;\n        private List<Authors> authors;\n\n        public String getImage() {\n            return image;\n        }\n\n        public void setImage(String image) {\n            this.image = image;\n        }\n\n        public boolean isIs_replyable() {\n            return is_replyable;\n        }\n\n        public void setIs_replyable(boolean is_replyable) {\n            this.is_replyable = is_replyable;\n        }\n\n        public String getPreface() {\n            return preface;\n        }\n\n        public void setPreface(String preface) {\n            this.preface = preface;\n        }\n\n        public int getId() {\n            return id;\n        }\n\n        public void setId(int id) {\n            this.id = id;\n        }\n\n        public Subject getSubject() {\n            return subject;\n        }\n\n        public void setSubject(Subject subject) {\n            this.subject = subject;\n        }\n\n        public boolean isIs_editor_recommend() {\n            return is_editor_recommend;\n        }\n\n        public void setIs_editor_recommend(boolean is_editor_recommend) {\n            this.is_editor_recommend = is_editor_recommend;\n        }\n\n        public String getCopyright() {\n            return copyright;\n        }\n\n        public void setCopyright(String copyright) {\n            this.copyright = copyright;\n        }\n\n        public Author getAuthor() {\n            return author;\n        }\n\n        public void setAuthor(Author author) {\n            this.author = author;\n        }\n\n        public String getImage_description() {\n            return image_description;\n        }\n\n        public void setImage_description(String image_description) {\n            this.image_description = image_description;\n        }\n\n        public String getContent() {\n            return content;\n        }\n\n        public void setContent(String content) {\n            this.content = content;\n        }\n\n        public boolean isIs_show_summary() {\n            return is_show_summary;\n        }\n\n        public void setIs_show_summary(boolean is_show_summary) {\n            this.is_show_summary = is_show_summary;\n        }\n\n        public String getMinisite_key() {\n            return minisite_key;\n        }\n\n        public void setMinisite_key(String minisite_key) {\n            this.minisite_key = minisite_key;\n        }\n\n        public ImageInfo getImage_info() {\n            return image_info;\n        }\n\n        public void setImage_info(ImageInfo image_info) {\n            this.image_info = image_info;\n        }\n\n        public String getSubject_key() {\n            return subject_key;\n        }\n\n        public void setSubject_key(String subject_key) {\n            this.subject_key = subject_key;\n        }\n\n        public Minisite getMinisite() {\n            return minisite;\n        }\n\n        public void setMinisite(Minisite minisite) {\n            this.minisite = minisite;\n        }\n\n        public String getDate_published() {\n            return date_published;\n        }\n\n        public void setDate_published(String date_published) {\n            this.date_published = date_published;\n        }\n\n        public String getVideo_content() {\n            return video_content;\n        }\n\n        public void setVideo_content(String video_content) {\n            this.video_content = video_content;\n        }\n\n        public int getReplies_count() {\n            return replies_count;\n        }\n\n        public void setReplies_count(int replies_count) {\n            this.replies_count = replies_count;\n        }\n\n        public boolean isIs_author_external() {\n            return is_author_external;\n        }\n\n        public void setIs_author_external(boolean is_author_external) {\n            this.is_author_external = is_author_external;\n        }\n\n        public int getRecommends_count() {\n            return recommends_count;\n        }\n\n        public void setRecommends_count(int recommends_count) {\n            this.recommends_count = recommends_count;\n        }\n\n        public String getTitle_hide() {\n            return title_hide;\n        }\n\n        public void setTitle_hide(String title_hide) {\n            this.title_hide = title_hide;\n        }\n\n        public String getDate_modified() {\n            return date_modified;\n        }\n\n        public void setDate_modified(String date_modified) {\n            this.date_modified = date_modified;\n        }\n\n        public String getUrl() {\n            return url;\n        }\n\n        public void setUrl(String url) {\n            this.url = url;\n        }\n\n        public String getTitle() {\n            return title;\n        }\n\n        public void setTitle(String title) {\n            this.title = title;\n        }\n\n        public String getSmall_image() {\n            return small_image;\n        }\n\n        public void setSmall_image(String small_image) {\n            this.small_image = small_image;\n        }\n\n        public String getSummary() {\n            return summary;\n        }\n\n        public void setSummary(String summary) {\n            this.summary = summary;\n        }\n\n        public String getUkey_author() {\n            return ukey_author;\n        }\n\n        public void setUkey_author(String ukey_author) {\n            this.ukey_author = ukey_author;\n        }\n\n        public String getDate_created() {\n            return date_created;\n        }\n\n        public void setDate_created(String date_created) {\n            this.date_created = date_created;\n        }\n\n        public String getResource_url() {\n            return resource_url;\n        }\n\n        public void setResource_url(String resource_url) {\n            this.resource_url = resource_url;\n        }\n\n        public List<?> getChannels() {\n            return channels;\n        }\n\n        public void setChannels(List<?> channels) {\n            this.channels = channels;\n        }\n\n        public List<?> getChannel_keys() {\n            return channel_keys;\n        }\n\n        public void setChannel_keys(List<?> channel_keys) {\n            this.channel_keys = channel_keys;\n        }\n\n        public List<String> getTags() {\n            return tags;\n        }\n\n        public void setTags(List<String> tags) {\n            this.tags = tags;\n        }\n\n        public List<Authors> getAuthors() {\n            return authors;\n        }\n\n        public void setAuthors(List<Authors> authors) {\n            this.authors = authors;\n        }\n\n        public static class Subject {\n            /**\n             * url : http://www.guokr.com/scientific/subject/medicine/\n             * date_created : 2014-05-23T16:22:09.282129+08:00\n             * name : 医学\n             * key : medicine\n             * articles_count : 1819\n             */\n\n            private String url;\n            private String date_created;\n            private String name;\n            private String key;\n            private int articles_count;\n\n            public String getUrl() {\n                return url;\n            }\n\n            public void setUrl(String url) {\n                this.url = url;\n            }\n\n            public String getDate_created() {\n                return date_created;\n            }\n\n            public void setDate_created(String date_created) {\n                this.date_created = date_created;\n            }\n\n            public String getName() {\n                return name;\n            }\n\n            public void setName(String name) {\n                this.name = name;\n            }\n\n            public String getKey() {\n                return key;\n            }\n\n            public void setKey(String key) {\n                this.key = key;\n            }\n\n            public int getArticles_count() {\n                return articles_count;\n            }\n\n            public void setArticles_count(int articles_count) {\n                this.articles_count = articles_count;\n            }\n        }\n\n        public static class Author {\n            /**\n             * ukey : 1jodqq\n             * is_title_authorized : true\n             * nickname : 飞刀断雨\n             * master_category : personal\n             * amended_reliability : 0\n             * is_exists : true\n             * title : 临床医学专业，玄牝之门小组管理员\n             * url : http://www.guokr.com/i/0093516434/\n             * gender : female\n             * followers_count : 221\n             * avatar : {\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"}\n             * resource_url : http://apis.guokr.com/community/user/1jodqq.json\n             */\n\n            private String ukey;\n            private boolean is_title_authorized;\n            private String nickname;\n            private String master_category;\n            private String amended_reliability;\n            private boolean is_exists;\n            private String title;\n            private String url;\n            private String gender;\n            private int followers_count;\n            private Avatar avatar;\n            private String resource_url;\n\n            public String getUkey() {\n                return ukey;\n            }\n\n            public void setUkey(String ukey) {\n                this.ukey = ukey;\n            }\n\n            public boolean isIs_title_authorized() {\n                return is_title_authorized;\n            }\n\n            public void setIs_title_authorized(boolean is_title_authorized) {\n                this.is_title_authorized = is_title_authorized;\n            }\n\n            public String getNickname() {\n                return nickname;\n            }\n\n            public void setNickname(String nickname) {\n                this.nickname = nickname;\n            }\n\n            public String getMaster_category() {\n                return master_category;\n            }\n\n            public void setMaster_category(String master_category) {\n                this.master_category = master_category;\n            }\n\n            public String getAmended_reliability() {\n                return amended_reliability;\n            }\n\n            public void setAmended_reliability(String amended_reliability) {\n                this.amended_reliability = amended_reliability;\n            }\n\n            public boolean isIs_exists() {\n                return is_exists;\n            }\n\n            public void setIs_exists(boolean is_exists) {\n                this.is_exists = is_exists;\n            }\n\n            public String getTitle() {\n                return title;\n            }\n\n            public void setTitle(String title) {\n                this.title = title;\n            }\n\n            public String getUrl() {\n                return url;\n            }\n\n            public void setUrl(String url) {\n                this.url = url;\n            }\n\n            public String getGender() {\n                return gender;\n            }\n\n            public void setGender(String gender) {\n                this.gender = gender;\n            }\n\n            public int getFollowers_count() {\n                return followers_count;\n            }\n\n            public void setFollowers_count(int followers_count) {\n                this.followers_count = followers_count;\n            }\n\n            public Avatar getAvatar() {\n                return avatar;\n            }\n\n            public void setAvatar(Avatar avatar) {\n                this.avatar = avatar;\n            }\n\n            public String getResource_url() {\n                return resource_url;\n            }\n\n            public void setResource_url(String resource_url) {\n                this.resource_url = resource_url;\n            }\n\n            public static class Avatar {\n                /**\n                 * large : https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\n                 * small : https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\n                 * normal : https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\n                 */\n\n                private String large;\n                private String small;\n                private String normal;\n\n                public String getLarge() {\n                    return large;\n                }\n\n                public void setLarge(String large) {\n                    this.large = large;\n                }\n\n                public String getSmall() {\n                    return small;\n                }\n\n                public void setSmall(String small) {\n                    this.small = small;\n                }\n\n                public String getNormal() {\n                    return normal;\n                }\n\n                public void setNormal(String normal) {\n                    this.normal = normal;\n                }\n            }\n        }\n\n        public static class ImageInfo {\n            /**\n             * url : https://2-im.guokr.com/bfjAMXmfv0qwjQtnzLVOpJt-vu98su4VvVcHR_sUoh9KAQAA8AAAAEpQ.jpg\n             * width : 330\n             * height : 240\n             */\n\n            private String url;\n            private int width;\n            private int height;\n\n            public String getUrl() {\n                return url;\n            }\n\n            public void setUrl(String url) {\n                this.url = url;\n            }\n\n            public int getWidth() {\n                return width;\n            }\n\n            public void setWidth(int width) {\n                this.width = width;\n            }\n\n            public int getHeight() {\n                return height;\n            }\n\n            public void setHeight(int height) {\n                this.height = height;\n            }\n        }\n\n        public static class Minisite {\n            /**\n             * name : 健康朝九晚五\n             * url : http://www.guokr.com/site/health/\n             * introduction : 每天的朝九晚五，上几篇健康小文，有趣、靠谱，还很给力\n             * key : health\n             * date_created : 2010-10-20T16:20:43+08:00\n             * icon : https://2-im.guokr.com/gDNaY8kFHIUnyDRLBlb1hWY3fwK9eAuV5icTVSuh7TNuAAAAWgAAAEpQ.jpg\n             */\n\n            private String name;\n            private String url;\n            private String introduction;\n            private String key;\n            private String date_created;\n            private String icon;\n\n            public String getName() {\n                return name;\n            }\n\n            public void setName(String name) {\n                this.name = name;\n            }\n\n            public String getUrl() {\n                return url;\n            }\n\n            public void setUrl(String url) {\n                this.url = url;\n            }\n\n            public String getIntroduction() {\n                return introduction;\n            }\n\n            public void setIntroduction(String introduction) {\n                this.introduction = introduction;\n            }\n\n            public String getKey() {\n                return key;\n            }\n\n            public void setKey(String key) {\n                this.key = key;\n            }\n\n            public String getDate_created() {\n                return date_created;\n            }\n\n            public void setDate_created(String date_created) {\n                this.date_created = date_created;\n            }\n\n            public String getIcon() {\n                return icon;\n            }\n\n            public void setIcon(String icon) {\n                this.icon = icon;\n            }\n        }\n\n        public static class Authors {\n            /**\n             * ukey : 1jodqq\n             * is_title_authorized : true\n             * nickname : 飞刀断雨\n             * master_category : personal\n             * amended_reliability : 0\n             * is_exists : true\n             * title : 临床医学专业，玄牝之门小组管理员\n             * url : http://www.guokr.com/i/0093516434/\n             * gender : female\n             * followers_count : 221\n             * avatar : {\"large\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\",\"small\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\",\"normal\":\"https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\"}\n             * resource_url : http://apis.guokr.com/community/user/1jodqq.json\n             */\n\n            private String ukey;\n            private boolean is_title_authorized;\n            private String nickname;\n            private String master_category;\n            private String amended_reliability;\n            private boolean is_exists;\n            private String title;\n            private String url;\n            private String gender;\n            private int followers_count;\n            private Object avatar;\n            private String resource_url;\n\n            public String getUkey() {\n                return ukey;\n            }\n\n            public void setUkey(String ukey) {\n                this.ukey = ukey;\n            }\n\n            public boolean isIs_title_authorized() {\n                return is_title_authorized;\n            }\n\n            public void setIs_title_authorized(boolean is_title_authorized) {\n                this.is_title_authorized = is_title_authorized;\n            }\n\n            public String getNickname() {\n                return nickname;\n            }\n\n            public void setNickname(String nickname) {\n                this.nickname = nickname;\n            }\n\n            public String getMaster_category() {\n                return master_category;\n            }\n\n            public void setMaster_category(String master_category) {\n                this.master_category = master_category;\n            }\n\n            public String getAmended_reliability() {\n                return amended_reliability;\n            }\n\n            public void setAmended_reliability(String amended_reliability) {\n                this.amended_reliability = amended_reliability;\n            }\n\n            public boolean isIs_exists() {\n                return is_exists;\n            }\n\n            public void setIs_exists(boolean is_exists) {\n                this.is_exists = is_exists;\n            }\n\n            public String getTitle() {\n                return title;\n            }\n\n            public void setTitle(String title) {\n                this.title = title;\n            }\n\n            public String getUrl() {\n                return url;\n            }\n\n            public void setUrl(String url) {\n                this.url = url;\n            }\n\n            public String getGender() {\n                return gender;\n            }\n\n            public void setGender(String gender) {\n                this.gender = gender;\n            }\n\n            public int getFollowers_count() {\n                return followers_count;\n            }\n\n            public void setFollowers_count(int followers_count) {\n                this.followers_count = followers_count;\n            }\n\n            public Object getAvatar() {\n                return avatar;\n            }\n\n            public void setAvatar(Object avatar) {\n                this.avatar = avatar;\n            }\n\n            public String getResource_url() {\n                return resource_url;\n            }\n\n            public void setResource_url(String resource_url) {\n                this.resource_url = resource_url;\n            }\n\n            public static class AvatarX {\n                /**\n                 * large : https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/160/h/160\n                 * small : https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/24/h/24\n                 * normal : https://3-im.guokr.com/1XElhEGExSSNXC7Z3F2ZC_M7akiW_uq9rKeXbAwVotQ4AAAAOAAAAFBO.png?imageView2/1/w/48/h/48\n                 */\n\n                private String large;\n                private String small;\n                private String normal;\n\n                public String getLarge() {\n                    return large;\n                }\n\n                public void setLarge(String large) {\n                    this.large = large;\n                }\n\n                public String getSmall() {\n                    return small;\n                }\n\n                public void setSmall(String small) {\n                    this.small = small;\n                }\n\n                public String getNormal() {\n                    return normal;\n                }\n\n                public void setNormal(String normal) {\n                    this.normal = normal;\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "guokr/src/main/java/me/shouheng/guokr/model/repository/GuokrRetrofit.java",
    "content": "package me.shouheng.guokr.model.repository;\n\nimport java.util.concurrent.TimeUnit;\n\nimport okhttp3.OkHttpClient;\nimport retrofit2.Retrofit;\nimport retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;\nimport retrofit2.converter.gson.GsonConverterFactory;\n\n/**\n * Created by WngShhng on 2018/7/30.*/\npublic class GuokrRetrofit {\n\n    public static GuokrService getGuokrService() {\n        return new Retrofit.Builder()\n                .baseUrl(\"http://apis.guokr.com/minisite/\")\n                .addConverterFactory(GsonConverterFactory.create())\n                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())\n                .client(getOkHttpClient())\n                .build().create(GuokrService.class);\n    }\n\n    private static OkHttpClient getOkHttpClient() {\n        return new OkHttpClient.Builder()\n                .connectTimeout(10, TimeUnit.SECONDS)\n                .readTimeout(10, TimeUnit.SECONDS)\n                .writeTimeout(10, TimeUnit.SECONDS)\n                .build();\n    }\n}\n"
  },
  {
    "path": "guokr/src/main/java/me/shouheng/guokr/model/repository/GuokrService.java",
    "content": "package me.shouheng.guokr.model.repository;\n\nimport io.reactivex.Observable;\nimport me.shouheng.guokr.model.data.GuokrNews;\nimport me.shouheng.guokr.model.data.GuokrNewsContent;\nimport retrofit2.http.GET;\nimport retrofit2.http.Path;\nimport retrofit2.http.Query;\n\n/**\n * @author shouh\n * @version $Id: GuokrService, v 0.1 2018/6/10 11:11 shouh Exp$\n */\npublic interface GuokrService {\n\n    @GET(\"article.json?retrieve_type=by_minisite\")\n    Observable<GuokrNews> getNews(@Query(\"offset\") int offset, @Query(\"limit\") int limit);\n\n    @GET(\"article/{id}.json\")\n    Observable<GuokrNewsContent> getGuokrContent(@Path(\"id\") int id);\n}\n"
  },
  {
    "path": "guokr/src/main/java/me/shouheng/guokr/view/GuokrNewsActivity.java",
    "content": "package me.shouheng.guokr.view;\n\nimport android.os.Bundle;\nimport androidx.fragment.app.Fragment;\nimport androidx.appcompat.app.ActionBar;\nimport androidx.appcompat.widget.Toolbar;\nimport android.view.MenuItem;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.alibaba.android.arouter.launcher.ARouter;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.FragmentHelper;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.guokr.R;\nimport me.shouheng.guokr.databinding.ActivityGuokrBewsBinding;\nimport me.shouheng.guokr.model.data.GuokrNews;\nimport me.shouheng.guokr.view.fragment.NewsListFragment;\n\n@Route(path = BaseConstants.GUOKR_NEWS)\npublic class GuokrNewsActivity extends CommonActivity<ActivityGuokrBewsBinding> implements NewsListFragment.FragmentInteraction {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_guokr_bews;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        configToolbar();\n\n        toFragment((Fragment) ARouter.getInstance().build(BaseConstants.GUOKR_NEWS_LIST).navigation());\n    }\n\n    private void configToolbar() {\n        Toolbar toolbar = getBinding().barLayout.toolbar;\n        toolbar.setBackgroundResource(R.color.light_theme_background);\n        setSupportActionBar(toolbar);\n        ActionBar actionBar = getSupportActionBar();\n        if (actionBar != null) {\n            actionBar.setTitle(R.string.menu_item_title_2);\n            actionBar.setSubtitle(R.string.menu_item_desc_2);\n            actionBar.setDisplayHomeAsUpEnabled(true);\n        }\n    }\n\n    private void toFragment(Fragment fragment) {\n        FragmentHelper.replace(this, fragment, R.id.fragment_container);\n    }\n\n    private void toFragmentWithCallback(Fragment fragment) {\n        FragmentHelper.replaceWithCallback(this, fragment, R.id.fragment_container);\n    }\n\n    @Override\n    public void onArticleClicked(GuokrNews.Result result) {\n        Fragment fragment = (Fragment) ARouter.getInstance()\n                .build(BaseConstants.GUOKR_NEWS_DETAIL)\n                .withInt(BaseConstants.GUOKR_NEWS_DETAIL_EXTRA_KEY_ARTICLE_ID, result.getId())\n                .withString(BaseConstants.GUOKR_NEWS_DETAIL_EXTRA_KEY_ARTICLE_TITLE, result.getTitle())\n                .navigation();\n        toFragmentWithCallback(fragment);\n    }\n\n    @Override\n    public boolean onOptionsItemSelected(MenuItem item) {\n        switch (item.getItemId()) {\n            case android.R.id.home:\n                super.onBackPressed();\n                break;\n        }\n        return super.onOptionsItemSelected(item);\n    }\n}\n"
  },
  {
    "path": "guokr/src/main/java/me/shouheng/guokr/view/adapter/GuokrNewsAdapter.java",
    "content": "package me.shouheng.guokr.view.adapter;\n\nimport android.content.Context;\nimport android.widget.ImageView;\n\nimport com.chad.library.adapter.base.BaseQuickAdapter;\nimport com.chad.library.adapter.base.BaseViewHolder;\n\nimport java.util.LinkedList;\n\nimport me.shouheng.commons.tools.TimeUtils;\nimport me.shouheng.commons.tools.glide.GlideApp;\nimport me.shouheng.guokr.R;\nimport me.shouheng.guokr.model.data.GuokrNews;\n\n/**\n * @author shouh\n * @version $Id: GuokrNewsAdapter, v 0.1 2018/6/10 13:41 shouh Exp$\n */\npublic class GuokrNewsAdapter extends BaseQuickAdapter<GuokrNews.Result, BaseViewHolder> {\n\n    private Context context;\n\n    public GuokrNewsAdapter(Context context) {\n        super(R.layout.item_guokr_news, new LinkedList<>());\n        this.context = context;\n    }\n\n    @Override\n    protected void convert(BaseViewHolder helper, GuokrNews.Result item) {\n        helper.setText(R.id.tv_title, item.getTitle());\n        helper.setText(R.id.tv_tags, item.getSubject().getName());\n\n        GlideApp.with(context)\n                .asBitmap()\n                .load(item.getSmall_image())\n                .placeholder(R.drawable.guokr)\n                .centerCrop()\n                .into((ImageView) helper.getView(R.id.iv_cover));\n\n        GlideApp.with(context)\n                .asBitmap()\n                .load(item.getAuthor().getAvatar().getNormal())\n                .placeholder(R.drawable.guokr)\n                .centerCrop()\n                .into((ImageView) helper.getView(R.id.civ_author));\n        helper.setText(R.id.tv_author, item.getAuthor().getNickname());\n        helper.setText(R.id.tv_date, TimeUtils.getPrettyTime(TimeUtils.from(item.getDate_published())));\n    }\n}\n"
  },
  {
    "path": "guokr/src/main/java/me/shouheng/guokr/view/fragment/NewsDetailFragment.java",
    "content": "package me.shouheng.guokr.view.fragment;\n\nimport android.annotation.SuppressLint;\nimport android.app.Activity;\nimport androidx.lifecycle.ViewModelProviders;\nimport android.os.Bundle;\nimport androidx.appcompat.app.ActionBar;\nimport androidx.appcompat.app.AppCompatActivity;\nimport android.webkit.WebResourceRequest;\nimport android.webkit.WebSettings;\nimport android.webkit.WebView;\nimport android.webkit.WebViewClient;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.ToastUtils;\nimport me.shouheng.commons.view.fragment.CommonFragment;\nimport me.shouheng.guokr.R;\nimport me.shouheng.guokr.databinding.FragmentNewsDetailBinding;\nimport me.shouheng.guokr.model.data.GuokrNewsContent;\nimport me.shouheng.guokr.viewmodel.GuokrViewModel;\n\n/**\n * @author shouh\n * @version $Id: NewsDetailFragment, v 0.1 2018/6/10 19:02 shouh Exp$\n */\n@Route(path = BaseConstants.GUOKR_NEWS_DETAIL)\npublic class NewsDetailFragment extends CommonFragment<FragmentNewsDetailBinding> {\n\n    private int articleId;\n\n    private String articleTitle;\n\n    private GuokrViewModel guokrViewModel;\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.fragment_news_detail;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        handleArguments();\n\n        configToolbar();\n\n        configViews();\n\n        guokrViewModel = ViewModelProviders.of(this).get(GuokrViewModel.class);\n\n        registerObservers();\n\n        guokrViewModel.fetchGuokrNewsContent(articleId);\n    }\n\n    private void handleArguments() {\n        Bundle args = getArguments();\n        assert args != null;\n        articleId = args.getInt(BaseConstants.GUOKR_NEWS_DETAIL_EXTRA_KEY_ARTICLE_ID);\n        articleTitle = args.getString(BaseConstants.GUOKR_NEWS_DETAIL_EXTRA_KEY_ARTICLE_TITLE);\n    }\n\n    private void configToolbar() {\n        Activity activity = getActivity();\n        if (activity != null) {\n            ActionBar actionBar = ((AppCompatActivity) activity).getSupportActionBar();\n            if (actionBar != null) {\n                actionBar.setTitle(articleTitle);\n                actionBar.setSubtitle(\"\");\n            }\n        }\n    }\n\n    @SuppressLint(\"SetJavaScriptEnabled\")\n    private void configViews() {\n        getBinding().wv.setScrollbarFadingEnabled(true);\n        getBinding().wv.getSettings().setJavaScriptEnabled(true);\n        getBinding().wv.getSettings().setBuiltInZoomControls(false);\n        getBinding().wv.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);\n        getBinding().wv.getSettings().setDomStorageEnabled(true);\n        getBinding().wv.getSettings().setAppCacheEnabled(true);\n        getBinding().wv.getSettings().setBlockNetworkImage(false);\n        getBinding().wv.setHorizontalScrollBarEnabled(false);\n        getBinding().wv.setWebViewClient(new WebViewClient() {\n            @Override\n            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {\n                return true;\n            }\n        });\n    }\n\n    private void registerObservers() {\n        guokrViewModel.getGuokrNewsContentLiveData().observe(this, resources -> {\n            if (resources == null) return;\n            switch (resources.status) {\n                case SUCCESS:\n                    assert resources.data != null;\n                    updateContent(resources.data);\n                    break;\n                case FAILED:\n                    ToastUtils.makeToast(resources.message);\n                    break;\n            }\n        });\n    }\n\n    private void updateContent(GuokrNewsContent content) {\n        String body = content.getResult().getContent();\n        String css = \"<div class=\\\"article\\\" id=\\\"contentMain\\\">\";\n        String result = (\"<!DOCTYPE html>\\n\"\n                + \"<html lang=\\\"ZH-CN\\\" xmlns=\\\"http://www.w3.org/1999/xhtml\\\">\\n\"\n                + \"<head>\\n<meta charset=\\\"utf-8\\\" />\\n\"\n                + \"\\n<link rel=\\\"stylesheet\\\" href=\\\"file:///android_asset/guokr_master.css\\\" />\\n\"\n                + css\n                + \"<script src=\\\"file:///android_asset/guokr.base.js\\\"></script>\\n\"\n                + \"<script src=\\\"file:///android_asset/guokr.articleInline.js\\\"></script>\"\n                + \"<script>\\n\"\n                + \"var ukey = null;\\n\"\n                + \"</script>\\n\"\n                + \"\\n</head>\\n<div class=\\\"content\\\" id=\\\"articleContent\\\"><body>\\n\"\n                + body\n                + \"\\n</div></body>\\n</html>\");\n        getBinding().wv.loadDataWithBaseURL(\"x-data://base\", result, \"text/html\", \"utf-8\", null);\n    }\n}\n"
  },
  {
    "path": "guokr/src/main/java/me/shouheng/guokr/view/fragment/NewsListFragment.java",
    "content": "package me.shouheng.guokr.view.fragment;\n\nimport android.app.Activity;\nimport androidx.lifecycle.ViewModelProviders;\nimport android.os.Bundle;\nimport androidx.appcompat.app.ActionBar;\nimport androidx.appcompat.app.AppCompatActivity;\nimport androidx.recyclerview.widget.LinearLayoutManager;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.ToastUtils;\nimport me.shouheng.commons.view.fragment.CommonFragment;\nimport me.shouheng.commons.view.widget.DividerItemDecoration;\nimport me.shouheng.guokr.R;\nimport me.shouheng.guokr.databinding.FragmentNewsListBinding;\nimport me.shouheng.guokr.model.data.GuokrNews;\nimport me.shouheng.guokr.view.adapter.GuokrNewsAdapter;\nimport me.shouheng.guokr.viewmodel.GuokrViewModel;\n\n/**\n * @author shouh\n * @version $Id: NewsListFragment, v 0.1 2018/6/10 12:08 shouh Exp$\n */\n@Route(path = BaseConstants.GUOKR_NEWS_LIST)\npublic class NewsListFragment extends CommonFragment<FragmentNewsListBinding> {\n\n    private GuokrViewModel guokrViewModel;\n\n    private GuokrNewsAdapter adapter;\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.fragment_news_list;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        Activity activity = getActivity();\n        if (!(activity instanceof FragmentInteraction)) {\n            throw new IllegalArgumentException(\"The associated activity must implement FragmentInteraction\");\n        }\n\n        guokrViewModel = ViewModelProviders.of(this).get(GuokrViewModel.class);\n\n        configViews();\n\n        registerObservers();\n\n        guokrViewModel.fetchFirstPage();\n    }\n\n    @Override\n    public void onResume() {\n        super.onResume();\n        Activity activity = getActivity();\n        if (activity != null) {\n            ActionBar actionBar = ((AppCompatActivity) activity).getSupportActionBar();\n            if (actionBar != null) {\n                actionBar.setTitle(R.string.menu_item_title_2);\n                actionBar.setSubtitle(R.string.menu_item_desc_2);\n            }\n        }\n    }\n\n    private void configViews() {\n        adapter = new GuokrNewsAdapter(getContext());\n        adapter.setOnItemClickListener(((adapter1, view, position) -> {\n            GuokrNews.Result result = adapter.getData().get(position);\n            Activity activity = getActivity();\n            if (activity != null) ((FragmentInteraction) activity).onArticleClicked(result);\n        }));\n        adapter.setEnableLoadMore(true);\n        adapter.setOnLoadMoreListener(() -> guokrViewModel.fetchNextPage(), getBinding().rv);\n\n        getBinding().rv.setAdapter(adapter);\n        getBinding().rv.addItemDecoration(new DividerItemDecoration(getContext(),\n                DividerItemDecoration.VERTICAL_LIST, false));\n        getBinding().rv.setLayoutManager(new LinearLayoutManager(getContext()));\n    }\n\n    private void registerObservers() {\n        guokrViewModel.getGuokrNewsLiveData().observe(this, resources -> {\n            if (resources == null) return;\n            switch (resources.status) {\n                case FAILED:\n                    ToastUtils.makeToast(resources.message);\n                    break;\n                case SUCCESS:\n                    adapter.addData(resources.data.getResult());\n                    adapter.notifyDataSetChanged();\n                    break;\n            }\n        });\n    }\n\n    public interface FragmentInteraction {\n        void onArticleClicked(GuokrNews.Result result);\n    }\n}\n"
  },
  {
    "path": "guokr/src/main/java/me/shouheng/guokr/viewmodel/GuokrViewModel.java",
    "content": "package me.shouheng.guokr.viewmodel;\n\nimport androidx.lifecycle.LiveData;\nimport androidx.lifecycle.MutableLiveData;\nimport androidx.lifecycle.ViewModel;\n\nimport io.reactivex.Observer;\nimport io.reactivex.android.schedulers.AndroidSchedulers;\nimport io.reactivex.disposables.Disposable;\nimport io.reactivex.schedulers.Schedulers;\nimport me.shouheng.commons.model.Resource;\nimport me.shouheng.guokr.model.data.GuokrNews;\nimport me.shouheng.guokr.model.data.GuokrNewsContent;\nimport me.shouheng.guokr.model.repository.GuokrRetrofit;\n\n/**\n * @author shouh\n * @version $Id: GuokrViewModel, v 0.1 2018/6/10 11:10 shouh Exp$\n */\npublic class GuokrViewModel extends ViewModel {\n\n    private int offset = 0;\n\n    private final int limit = 20;\n\n    private MutableLiveData<Resource<GuokrNews>> guokrNewsLiveData;\n\n    private MutableLiveData<Resource<GuokrNewsContent>> guokrNewsContentLiveData;\n\n    public LiveData<Resource<GuokrNews>> getGuokrNewsLiveData() {\n        if (guokrNewsLiveData == null) {\n            guokrNewsLiveData = new MutableLiveData<>();\n        }\n        return guokrNewsLiveData;\n    }\n\n    public LiveData<Resource<GuokrNewsContent>> getGuokrNewsContentLiveData() {\n        if (guokrNewsContentLiveData == null) {\n            guokrNewsContentLiveData = new MutableLiveData<>();\n        }\n        return guokrNewsContentLiveData;\n    }\n\n    public void fetchFirstPage() {\n        fetchGuokrNews(offset, limit);\n    }\n\n    public void fetchNextPage() {\n        offset += limit;\n        fetchGuokrNews(offset, limit);\n    }\n\n    private void fetchGuokrNews(int offset, int limit) {\n        offset += limit;\n        GuokrRetrofit.getGuokrService().getNews(offset, limit)\n                .subscribeOn(Schedulers.io())\n                .observeOn(AndroidSchedulers.mainThread())\n                .subscribe(new Observer<GuokrNews>() {\n                    @Override\n                    public void onError(Throwable e) {\n                        guokrNewsLiveData.setValue(Resource.error(e.getMessage(), null));\n                    }\n\n                    @Override\n                    public void onComplete() { }\n\n                    @Override\n                    public void onSubscribe(Disposable d) { }\n\n                    @Override\n                    public void onNext(GuokrNews guokrNews) {\n                        guokrNewsLiveData.setValue(Resource.success(guokrNews));\n                    }\n                });\n    }\n\n    public void fetchGuokrNewsContent(int id) {\n        GuokrRetrofit.getGuokrService().getGuokrContent(id)\n                .subscribeOn(Schedulers.io())\n                .observeOn(AndroidSchedulers.mainThread())\n                .subscribe(new Observer<GuokrNewsContent>() {\n                    @Override\n                    public void onError(Throwable e) {\n                        guokrNewsContentLiveData.setValue(Resource.error(e.getMessage(), null));\n                    }\n\n                    @Override\n                    public void onComplete() { }\n\n                    @Override\n                    public void onSubscribe(Disposable d) { }\n\n                    @Override\n                    public void onNext(GuokrNewsContent guokrNewsContent) {\n                        guokrNewsContentLiveData.setValue(Resource.success(guokrNewsContent));\n                    }\n                });\n    }\n}\n"
  },
  {
    "path": "guokr/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillColor=\"#26A69A\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n"
  },
  {
    "path": "guokr/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillType=\"evenOdd\"\n        android:pathData=\"M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"78.5885\"\n                android:endY=\"90.9159\"\n                android:startX=\"48.7653\"\n                android:startY=\"61.0927\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        android:pathData=\"M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\" />\n</vector>\n"
  },
  {
    "path": "guokr/src/main/res/layout/activity_guokr_bews.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:tools=\"http://schemas.android.com/tools\"\n    tools:context=\".view.guokr.GuokrNewsActivity\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <RelativeLayout\n        android:fitsSystemWindows=\"true\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <include android:id=\"@+id/bar_layout\" layout=\"@layout/layout_toolbar\"/>\n\n        <FrameLayout\n            android:id=\"@+id/fragment_container\"\n            android:layout_below=\"@id/bar_layout\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"/>\n\n        <View android:layout_below=\"@id/bar_layout\"\n            android:background=\"@drawable/bg_toolbar_shade\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"5dp\"/>\n\n    </RelativeLayout>\n\n</layout>"
  },
  {
    "path": "guokr/src/main/res/layout/fragment_news_detail.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <WebView\n        android:id=\"@+id/wv\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"/>\n\n</layout>"
  },
  {
    "path": "guokr/src/main/res/layout/fragment_news_list.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:id=\"@+id/rv\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"/>\n\n</layout>"
  },
  {
    "path": "guokr/src/main/res/layout/item_guokr_news.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"100dp\"\n    android:background=\"?android:attr/selectableItemBackground\"\n    android:orientation=\"horizontal\">\n\n    <RelativeLayout\n        android:orientation=\"vertical\"\n        android:layout_margin=\"8dp\"\n        android:gravity=\"center_vertical\"\n        android:layout_weight=\"1\"\n        android:layout_width=\"0dp\"\n        android:layout_height=\"match_parent\">\n\n        <LinearLayout\n            android:id=\"@+id/ll_info\"\n            android:gravity=\"center_vertical\"\n            android:orientation=\"horizontal\"\n            android:layout_alignParentBottom=\"true\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\">\n\n            <me.shouheng.commons.view.widget.CircleImageView\n                android:id=\"@+id/civ_author\"\n                tools:src=\"@color/colorAccent\"\n                android:layout_width=\"16dp\"\n                android:layout_height=\"16dp\" />\n\n            <androidx.appcompat.widget.AppCompatTextView\n                android:id=\"@+id/tv_author\"\n                tools:text=\"Sub title\"\n                android:layout_marginStart=\"8dp\"\n                android:textSize=\"12sp\"\n                android:singleLine=\"true\"\n                android:ellipsize=\"end\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\" />\n\n            <androidx.appcompat.widget.AppCompatTextView\n                android:id=\"@+id/tv_date\"\n                tools:text=\"3天前\"\n                android:layout_marginStart=\"8dp\"\n                android:textSize=\"12sp\"\n                android:singleLine=\"true\"\n                android:ellipsize=\"end\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\" />\n\n        </LinearLayout>\n\n        <LinearLayout\n            android:layout_above=\"@id/ll_info\"\n            android:gravity=\"center_vertical\"\n            android:orientation=\"vertical\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\">\n\n            <androidx.appcompat.widget.AppCompatTextView\n                android:id=\"@+id/tv_title\"\n                tools:text=\"This is the fucking long title test, wow you may wonder why???? BALABALABALA\"\n                android:textSize=\"16sp\"\n                android:textColor=\"@android:color/black\"\n                android:maxLines=\"2\"\n                android:ellipsize=\"end\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"/>\n\n            <androidx.appcompat.widget.AppCompatTextView\n                android:id=\"@+id/tv_tags\"\n                tools:text=\"Sub title\"\n                android:layout_marginTop=\"4dp\"\n                android:textSize=\"12sp\"\n                android:singleLine=\"true\"\n                android:ellipsize=\"end\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\" />\n\n        </LinearLayout>\n\n    </RelativeLayout>\n\n    <me.shouheng.commons.view.widget.SquareImageView\n        android:id=\"@+id/iv_cover\"\n        tools:src=\"@color/colorAccent\"\n        android:layout_gravity=\"center_vertical\"\n        android:layout_height=\"100dp\"\n        android:layout_width=\"100dp\" />\n\n</LinearLayout>"
  },
  {
    "path": "guokr/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "guokr/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "guokr/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Guokr</string>\n</resources>\n"
  },
  {
    "path": "guokr/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.NoActionBar\">\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "guokr/src/test/java/me/shouheng/guokr/ExampleUnitTest.java",
    "content": "package me.shouheng.guokr;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "knife-annotation/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "knife-annotation/build.gradle",
    "content": "apply plugin: 'java-library'\n\ndependencies {\n    implementation fileTree(dir: 'libs', include: ['*.jar'])\n}\n\nsourceCompatibility = \"1.8\"\ntargetCompatibility = \"1.8\"\n"
  },
  {
    "path": "knife-annotation/src/main/java/me/shouheng/knife/annotation/BindView.java",
    "content": "package me.shouheng.knife.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * 用来将View与指定的id进行绑定\n *\n * @author shouh\n * @version $Id: BindView, v 0.1 2018/8/22 22:22 shouh Exp$\n */\n@Target(ElementType.FIELD)\n@Retention(RetentionPolicy.CLASS)\npublic @interface BindView {\n\n    /**\n     * 与该View进行绑定的id\n     *\n     * @return id\n     */\n    int id();\n}\n"
  },
  {
    "path": "knife-annotation/src/main/java/me/shouheng/knife/annotation/OnClick.java",
    "content": "package me.shouheng.knife.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * 将单击事件与指定的多个id绑定到一起\n *\n * @author shouh\n * @version $Id: OnClick, v 0.1 2018/8/22 22:20 shouh Exp$\n */\n@Target(ElementType.METHOD)\n@Retention(RetentionPolicy.CLASS)\npublic @interface OnClick {\n\n    /**\n     * 与该单击事件进行绑定的多个 id\n     *\n     * @return 用于绑定的多个 id\n     */\n    int[] ids();\n}\n"
  },
  {
    "path": "knife-api/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "knife-api/build.gradle",
    "content": "apply plugin: 'com.android.library'\n\nandroid {\n    compileSdkVersion 27\n    defaultConfig {\n        minSdkVersion 17\n        targetSdkVersion 27\n        versionCode 1\n        versionName \"1.0\"\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n}\n\ndependencies {\n    implementation fileTree(include: ['*.jar'], dir: 'libs')\n    testImplementation 'junit:junit:4.12'\n    androidTestImplementation 'androidx.test:runner:1.1.0'\n}\n"
  },
  {
    "path": "knife-api/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"me.shouheng.knife.api\">\n\n    <application\n        android:allowBackup=\"true\"\n        android:label=\"@string/app_name\"\n        android:supportsRtl=\"true\"/>\n\n</manifest>"
  },
  {
    "path": "knife-api/src/main/java/me/shouheng/knife/api/Injector.java",
    "content": "package me.shouheng.knife.api;\n\nimport me.shouheng.knife.api.finder.Finder;\n\n/**\n * @author shouh\n * @version $Id: Injector, v 0.1 2018/8/22 22:41 shouh Exp$\n */\npublic interface Injector<T> {\n\n    void inject(T host, Object source, Finder finder);\n}\n"
  },
  {
    "path": "knife-api/src/main/java/me/shouheng/knife/api/MyKnife.java",
    "content": "package me.shouheng.knife.api;\n\nimport android.app.Activity;\nimport android.view.View;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport me.shouheng.knife.api.finder.ActivityFinder;\nimport me.shouheng.knife.api.finder.Finder;\nimport me.shouheng.knife.api.finder.ViewFinder;\n\n/**\n * @author shouh\n * @version $Id: MyKnife, v 0.1 2018/8/22 22:50 shouh Exp$\n */\npublic class MyKnife {\n\n    public MyKnife() {\n        throw new AssertionError(\"Not available for instance\");\n    }\n\n    private final static ActivityFinder ACTIVITY_FINDER = new ActivityFinder();\n\n    private final static ViewFinder VIEW_FINDER = new ViewFinder();\n\n    private final static Map<String, Injector> FINDER_MAPPER = new HashMap<>();\n\n    public static void bind(Activity activity) {\n        bind(activity, activity, ACTIVITY_FINDER);\n    }\n\n    public static void bind(View view) {\n        bind(view, view);\n    }\n\n    public static void bind(Object host, View view) {\n        bind(host, view, VIEW_FINDER);\n    }\n\n    public static void bind(Object host, Object source, Finder finder) {\n        String className = host.getClass().getName();\n        try {\n            Injector injector = FINDER_MAPPER.get(className);\n            if (injector == null) {\n                Class<?> finderClass = Class.forName(className + \"$$Injector\");\n                injector = (Injector) finderClass.newInstance();\n                FINDER_MAPPER.put(className, injector);\n            }\n            injector.inject(host, source, finder);\n        } catch (ClassNotFoundException e) {\n            e.printStackTrace();\n        } catch (IllegalAccessException e) {\n            e.printStackTrace();\n        } catch (InstantiationException e) {\n            e.printStackTrace();\n        }\n    }\n}\n"
  },
  {
    "path": "knife-api/src/main/java/me/shouheng/knife/api/Unbinder.java",
    "content": "package me.shouheng.knife.api;\n\n/**\n * @author shouh\n * @version $Id: Unbinder, v 0.1 2018/8/22 22:42 shouh Exp$\n */\npublic interface Unbinder {\n\n    void unbind();\n\n    Unbinder EMPTY = new Unbinder() {\n        @Override\n        public void unbind() {\n\n        }\n    };\n}\n"
  },
  {
    "path": "knife-api/src/main/java/me/shouheng/knife/api/finder/ActivityFinder.java",
    "content": "package me.shouheng.knife.api.finder;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport android.view.View;\n\n/**\n * @author shouh\n * @version $Id: ActivityFinder, v 0.1 2018/8/22 22:34 shouh Exp$\n */\npublic class ActivityFinder implements Finder {\n\n    @Override\n    public Context getContext(Object source) {\n        return (Activity) source;\n    }\n\n    @Override\n    public View findView(Object source, int id) {\n        return ((Activity) source).findViewById(id);\n    }\n}\n"
  },
  {
    "path": "knife-api/src/main/java/me/shouheng/knife/api/finder/Finder.java",
    "content": "package me.shouheng.knife.api.finder;\n\nimport android.content.Context;\nimport android.view.View;\n\n/**\n * @author shouh\n * @version $Id: Finder, v 0.1 2018/8/22 22:27 shouh Exp$\n */\npublic interface Finder {\n\n    Context getContext(Object source);\n\n    View findView(Object source, int id);\n}\n"
  },
  {
    "path": "knife-api/src/main/java/me/shouheng/knife/api/finder/ViewFinder.java",
    "content": "package me.shouheng.knife.api.finder;\n\nimport android.content.Context;\nimport android.view.View;\n\n/**\n * @author shouh\n * @version $Id: ViewFinder, v 0.1 2018/8/22 22:45 shouh Exp$\n */\npublic class ViewFinder implements Finder {\n\n    @Override\n    public Context getContext(Object source) {\n        return ((View) source).getContext();\n    }\n\n    @Override\n    public View findView(Object source, int id) {\n        return ((View) source).findViewById(id);\n    }\n}\n"
  },
  {
    "path": "knife-api/src/main/res/values/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string name=\"app_name\">Knife api</string>\n</resources>"
  },
  {
    "path": "knife-compiler/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "knife-compiler/build.gradle",
    "content": "apply plugin: 'java-library'\n\ndependencies {\n    implementation fileTree(dir: 'libs', include: ['*.jar'])\n    compile 'com.squareup:javapoet:1.8.0'\n    compile 'com.google.auto.service:auto-service:1.0-rc2'\n    compile project(':knife-annotation')\n}\n\nsourceCompatibility = \"1.8\"\ntargetCompatibility = \"1.8\"\n"
  },
  {
    "path": "knife-compiler/src/main/java/me/shouheng/knife/compiler/BindViewProcessor.java",
    "content": "package me.shouheng.knife.compiler;\n\nimport com.google.auto.service.AutoService;\n\nimport java.util.HashMap;\nimport java.util.LinkedHashSet;\nimport java.util.Map;\nimport java.util.Set;\n\nimport javax.annotation.processing.AbstractProcessor;\nimport javax.annotation.processing.Filer;\nimport javax.annotation.processing.Messager;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.annotation.processing.Processor;\nimport javax.annotation.processing.RoundEnvironment;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.util.Elements;\nimport javax.tools.Diagnostic;\n\nimport me.shouheng.knife.annotation.BindView;\nimport me.shouheng.knife.annotation.OnClick;\nimport me.shouheng.knife.compiler.model.AnnotatedClass;\nimport me.shouheng.knife.compiler.model.BindViewField;\nimport me.shouheng.knife.compiler.model.OnClickMethod;\n\n/**\n * @author shouh\n * @version $Id: BindViewProcessor, v 0.1 2018/8/23 22:22 shouh Exp$\n */\n@AutoService(Processor.class)\n//@SupportedAnnotationTypes(value = {})\n////@SupportedSourceVersion(value = SourceVersion.RELEASE_8)\npublic class BindViewProcessor extends AbstractProcessor {\n\n    private Filer filer;\n\n    private Elements elements;\n\n    private Messager messager;\n\n    private Map<String, AnnotatedClass> map = new HashMap<>();\n\n    @Override\n    public synchronized void init(ProcessingEnvironment processingEnvironment) {\n        super.init(processingEnvironment);\n        elements = processingEnvironment.getElementUtils();\n        messager = processingEnvironment.getMessager();\n        filer = processingEnvironment.getFiler();\n    }\n\n    @Override\n    public Set<String> getSupportedAnnotationTypes() {\n        Set<String> types = new LinkedHashSet<>();\n        types.add(BindView.class.getCanonicalName());\n        types.add(OnClick.class.getCanonicalName());\n        return types;\n    }\n\n    @Override\n    public SourceVersion getSupportedSourceVersion() {\n        return SourceVersion.latestSupported();\n    }\n\n    @Override\n    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {\n        map.clear();\n        try {\n            processBindView(roundEnvironment);\n            processOnClick(roundEnvironment);\n        } catch (IllegalArgumentException e) {\n            error(e.getMessage());\n            return true;\n        }\n\n        try {\n            for (AnnotatedClass annotatedClass : map.values()) {\n                info(\"generating file for %s\", annotatedClass.getFullClassName());\n                annotatedClass.generateFinder().writeTo(filer);\n            }\n        } catch (Exception e) {\n            e.printStackTrace();\n            error(\"Generate file failed,reason:%s\", e.getMessage());\n        }\n        return true;\n    }\n\n    private void processBindView(RoundEnvironment roundEnv) {\n        for (Element element : roundEnv.getElementsAnnotatedWith(BindView.class)) {\n            AnnotatedClass annotatedClass = getAnnotatedClass(element);\n            BindViewField field = new BindViewField(element);\n            annotatedClass.addField(field);\n            System.out.print(\"p_element=\" + element.getSimpleName() + \",p_set=\" + element.getModifiers());\n        }\n    }\n\n    private AnnotatedClass getAnnotatedClass(Element element) {\n        TypeElement encloseElement = (TypeElement) element.getEnclosingElement();\n        String fullClassName = encloseElement.getQualifiedName().toString();\n        AnnotatedClass annotatedClass = map.get(fullClassName);\n        if (annotatedClass == null) {\n            annotatedClass = new AnnotatedClass(encloseElement, elements);\n            map.put(fullClassName, annotatedClass);\n        }\n        return annotatedClass;\n    }\n\n    private void processOnClick(RoundEnvironment roundEnv) {\n        for (Element element : roundEnv.getElementsAnnotatedWith(OnClick.class)) {\n            AnnotatedClass annotatedClass = getAnnotatedClass(element);\n            OnClickMethod method = new OnClickMethod(element);\n            annotatedClass.addMethod(method);\n        }\n    }\n\n    private void error(String msg, Object... args) {\n        messager.printMessage(Diagnostic.Kind.ERROR, String.format(msg, args));\n    }\n\n    private void info(String msg, Object... args) {\n        messager.printMessage(Diagnostic.Kind.NOTE, String.format(msg, args));\n    }\n}\n"
  },
  {
    "path": "knife-compiler/src/main/java/me/shouheng/knife/compiler/TypeUtils.java",
    "content": "package me.shouheng.knife.compiler;\n\nimport com.squareup.javapoet.ClassName;\n\n/**\n * @author shouh\n * @version $Id: TypeUtils, v 0.1 2018/8/22 22:54 shouh Exp$\n */\npublic class TypeUtils {\n\n    public final static ClassName FINDER = ClassName.get(\"me.shouheng.knife.api.finder\", \"Finder\");\n\n    public final static ClassName ONCLICK_LISTENER = ClassName.get(\"android.view\", \"View\", \"OnClickListener\");\n\n    public final static ClassName ANDROID_VIEW = ClassName.get(\"android.view\", \"View\");\n\n    public static final ClassName INJECTOR = ClassName.get(\"me.shouheng.knife.api\", \"Injector\");\n}\n"
  },
  {
    "path": "knife-compiler/src/main/java/me/shouheng/knife/compiler/model/AnnotatedClass.java",
    "content": "package me.shouheng.knife.compiler.model;\n\nimport com.squareup.javapoet.ClassName;\nimport com.squareup.javapoet.JavaFile;\nimport com.squareup.javapoet.MethodSpec;\nimport com.squareup.javapoet.ParameterizedTypeName;\nimport com.squareup.javapoet.TypeName;\nimport com.squareup.javapoet.TypeSpec;\n\nimport java.util.LinkedList;\nimport java.util.List;\n\nimport javax.lang.model.element.Modifier;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.util.Elements;\n\nimport me.shouheng.knife.compiler.TypeUtils;\n\n/**\n * @author shouh\n * @version $Id: AnnotatedClass, v 0.1 2018/8/22 22:55 shouh Exp$\n */\npublic class AnnotatedClass {\n\n    private TypeElement typeElement;\n\n    private List<BindViewField> bindViewFields;\n\n    private List<OnClickMethod> onClickMethods;\n\n    private Elements elements;\n\n    public AnnotatedClass(TypeElement typeElement, Elements elements) {\n        this.typeElement = typeElement;\n        this.bindViewFields = new LinkedList<>();\n        this.onClickMethods = new LinkedList<>();\n        this.elements = elements;\n    }\n\n    public String getFullClassName() {\n        return typeElement.getQualifiedName().toString();\n    }\n\n    public void addField(BindViewField bindViewField) {\n        bindViewFields.add(bindViewField);\n    }\n\n    public void addMethod(OnClickMethod method) {\n        onClickMethods.add(method);\n    }\n\n    public JavaFile generateFinder() {\n        MethodSpec.Builder builder = MethodSpec.methodBuilder(\"inject\")\n                .addModifiers(Modifier.PUBLIC)\n                .addAnnotation(Override.class)\n                .addParameter(TypeName.get(typeElement.asType()), \"host\", Modifier.FINAL)\n                .addParameter(TypeName.OBJECT, \"source\")\n                .addParameter(TypeUtils.FINDER, \"finder\");\n        for (BindViewField field : bindViewFields) {\n            builder.addStatement(\"host.$N=($T)finder.findView(source, $L)\",\n                    field.getFieldName(),\n                    ClassName.get(field.getFieldType()),\n                    field.getViewId());\n        }\n        if (onClickMethods.size() > 0) {\n            builder.addStatement(\"$T listener\", TypeUtils.ONCLICK_LISTENER);\n        }\n        for (OnClickMethod method : onClickMethods) {\n            TypeSpec listener = TypeSpec.anonymousClassBuilder(\"\")\n                    .addSuperinterface(TypeUtils.ONCLICK_LISTENER)\n                    .addMethod(MethodSpec.methodBuilder(\"onClick\")\n                            .addAnnotation(Override.class)\n                            .addModifiers(Modifier.PUBLIC)\n                            .returns(TypeName.VOID)\n                            .addParameter(TypeUtils.ANDROID_VIEW, \"view\")\n                            .addStatement(\"host.$N()\", method.getMethodName())\n                            .build())\n                    .build();\n            builder.addStatement(\"listener = $L\", listener);\n            for (int id : method.getIds()) {\n                builder.addStatement(\"finder.findView(source, $L).setOnClickListener(listener)\", id);\n            }\n        }\n        String packageName = getPackageName(typeElement);\n        String className = getClassName(typeElement, packageName);\n        ClassName bindClassName = ClassName.get(packageName, className);\n\n        TypeSpec finderClass = TypeSpec.classBuilder(bindClassName.simpleName() + \"$$Injector\")\n                .addModifiers(Modifier.PUBLIC)\n                .addSuperinterface(ParameterizedTypeName.get(TypeUtils.INJECTOR, TypeName.get(typeElement.asType())))\n                .addMethod(builder.build())\n                .build();\n        return JavaFile.builder(packageName, finderClass).build();\n    }\n\n    private String getPackageName(TypeElement type) {\n        return elements.getPackageOf(type).getQualifiedName().toString();\n    }\n\n    private String getClassName(TypeElement type, String packageName) {\n        int packageLen = packageName.length() + 1;\n        return type.getQualifiedName().toString().substring(packageLen).replace('.', '$');\n    }\n}\n"
  },
  {
    "path": "knife-compiler/src/main/java/me/shouheng/knife/compiler/model/BindViewField.java",
    "content": "package me.shouheng.knife.compiler.model;\n\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ElementKind;\nimport javax.lang.model.element.Name;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.TypeMirror;\n\nimport me.shouheng.knife.annotation.BindView;\n\n/**\n * @author shouh\n * @version $Id: BindViewField, v 0.1 2018/8/22 22:56 shouh Exp$\n */\npublic class BindViewField {\n\n    private VariableElement variableElement;\n\n    private int viewId;\n\n    /**\n     * 使用 Element 初始化当前类\n     *\n     * @param element element\n     */\n    public BindViewField(Element element) {\n        if (element.getKind() != ElementKind.FIELD) {\n            throw new IllegalArgumentException(\"Only field can be annotated with %s\" + BindView.class.getSimpleName());\n        }\n        variableElement = (VariableElement) element;\n        BindView bindView = variableElement.getAnnotation(BindView.class);\n        viewId = bindView.id();\n        if (viewId < 0) {\n            throw new IllegalArgumentException(\"The id must > 0\");\n        }\n    }\n\n    public Name getFieldName() {\n        return variableElement.getSimpleName();\n    }\n\n    public int getViewId() {\n        return viewId;\n    }\n\n    public TypeMirror getFieldType() {\n        return variableElement.asType();\n    }\n}\n"
  },
  {
    "path": "knife-compiler/src/main/java/me/shouheng/knife/compiler/model/OnClickMethod.java",
    "content": "package me.shouheng.knife.compiler.model;\n\nimport java.util.List;\n\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ElementKind;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.Name;\nimport javax.lang.model.element.VariableElement;\n\nimport me.shouheng.knife.annotation.OnClick;\n\n/**\n * @author shouh\n * @version $Id: OnClickMethod, v 0.1 2018/8/22 22:56 shouh Exp$\n */\npublic class OnClickMethod {\n\n    private Name methodName;\n\n    private int[] ids;\n\n    public OnClickMethod(Element element) {\n        if (element.getKind() != ElementKind.METHOD) {\n            throw new IllegalArgumentException(String.format(\"Only method can be annotated with %s\", OnClick.class.getSimpleName()));\n        }\n        ExecutableElement executableElement = (ExecutableElement) element;\n        methodName = executableElement.getSimpleName();\n        OnClick onClick = executableElement.getAnnotation(OnClick.class);\n        ids = onClick.ids();\n        for (int id : ids) {\n            if (id < 0) {\n                throw new IllegalArgumentException(String.format(\"Must set valid ids for @%s\", OnClick.class.getSimpleName()));\n            }\n        }\n        List<? extends VariableElement> params = executableElement.getParameters();\n        if (params.size() > 0) {\n            throw new IllegalArgumentException(String.format(\"The method annotated with @%s must have no parameters\", OnClick.class.getSimpleName()));\n        }\n    }\n\n    public Name getMethodName() {\n        return methodName;\n    }\n\n    public int[] getIds() {\n        return ids;\n    }\n}\n"
  },
  {
    "path": "layout/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "layout/build.gradle",
    "content": "println isLayoutModuleApp.toBoolean()\n\nif (isLayoutModuleApp.toBoolean()) {\n    apply plugin: 'com.android.application'\n} else {\n    apply plugin: 'com.android.library'\n}\n\nandroid {\n    compileSdkVersion rootProject.ext.compileSdkVersion\n    defaultConfig {\n        minSdkVersion rootProject.ext.minSdkVersion\n        targetSdkVersion rootProject.ext.targetSdkVersion\n        versionCode 1\n        versionName \"1.0\"\n        multiDexEnabled true\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n        javaCompileOptions {\n            annotationProcessorOptions {\n                arguments = [moduleName: project.getName()]\n            }\n        }\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n    // use data binding\n    dataBinding {\n        enabled = true\n    }\n    // use java 8 language\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n    // use external libs folder\n    sourceSets {\n        main {\n            jniLibs.srcDirs = ['libs']\n            if (isLayoutModuleApp.toBoolean()) {\n                manifest.srcFile \"src/main/debug/AndroidManifest.xml\"\n            } else {\n                manifest.srcFile \"src/main/AndroidManifest.xml\"\n            }\n        }\n    }\n}\n\ndependencies {\n    implementation fileTree(dir: 'libs', include: ['*.jar'])\n    testImplementation 'junit:junit:4.12'\n    androidTestImplementation 'androidx.test:runner:1.1.0'\n    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'\n    // swipe back layout\n    implementation 'me.imid.swipebacklayout.lib:library:1.1.0'\n    // router\n    annotationProcessor 'com.alibaba:arouter-compiler:1.1.4'\n    // projects\n    implementation project(':commons')\n}\n"
  },
  {
    "path": "layout/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "layout/src/androidTest/java/me/shouheng/layout/ExampleInstrumentedTest.java",
    "content": "package me.shouheng.layout;\n\nimport android.content.Context;\nimport androidx.test.InstrumentationRegistry;\nimport androidx.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"me.shouheng.layout\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "layout/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"me.shouheng.layout\">\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <activity android:name=\".view.navigation.NavigationActivity\" />\n        <activity android:name=\".view.tabbed.TabbedActivity\" />\n        <activity android:name=\".view.scrolling.ScrollingActivity\" />\n        <activity android:name=\".view.collapse.CollapseBarStructure\" />\n        <activity android:name=\".view.bottomsheet.BottomSheetActivity\" />\n        <activity android:name=\".view.LayoutMenuActivity\" />\n        <activity\n            android:name=\".view.DrawerActivity\"\n            android:label=\"@string/title_activity_drawer\"\n            android:theme=\"@style/AppTheme\"/>\n        <activity android:name=\".view.views.ViewSystemActivity\"/>\n        <activity android:name=\".view.views.ViewAnimateActivity\"/>\n        <activity android:name=\".view.support28.Support28Activity\"/>\n        <activity android:name=\".view.support28.BottomAppBarActivity\"/>\n        <activity android:name=\".view.swipe.SwipeBackDemoActivity\"/>\n        <activity android:name=\".view.adapter.BeforeAdapter\"/>\n    </application>\n\n</manifest>"
  },
  {
    "path": "layout/src/main/debug/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"me.shouheng.layout\">\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\"\n        android:name=\".ModuleLayoutApp\">\n        <activity android:name=\".view.LayoutMenuActivity\"\n            android:theme=\"@style/AppTheme.Branded\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n        <activity android:name=\".view.navigation.NavigationActivity\" />\n        <activity android:name=\".view.tabbed.TabbedActivity\" />\n        <activity android:name=\".view.scrolling.ScrollingActivity\" />\n        <activity android:name=\".view.collapse.CollapseBarStructure\" />\n        <activity android:name=\".view.bottomsheet.BottomSheetActivity\"/>\n        <activity\n            android:name=\".view.DrawerActivity\"\n            android:label=\"@string/title_activity_drawer\"\n            android:theme=\"@style/AppTheme\"/>\n        <activity android:name=\".view.views.ViewSystemActivity\"/>\n        <activity android:name=\".view.views.ViewAnimateActivity\"/>\n        <activity android:name=\".view.support28.Support28Activity\"/>\n        <activity android:name=\".view.support28.BottomAppBarActivity\"/>\n        <activity android:name=\".view.swipe.SwipeBackDemoActivity\"/>\n        <activity android:name=\".view.adapter.BeforeAdapter\"/>\n        <activity android:name=\".view.ActivityEditLayout\"/>\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "layout/src/main/java/me/shouheng/layout/ModuleLayoutApp.java",
    "content": "package me.shouheng.layout;\n\nimport com.alibaba.android.arouter.launcher.ARouter;\n\nimport me.shouheng.commons.BaseApplication;\n\n/**\n * @author shouh\n * @version $Id: ModuleGuokrApp, v 0.1 2018/6/6 22:30 shouh Exp$\n */\npublic class ModuleLayoutApp extends BaseApplication {\n\n    private static ModuleLayoutApp application;\n\n    public static ModuleLayoutApp getContext() {\n        return application;\n    }\n\n    @Override\n    public void onCreate() {\n        super.onCreate();\n        application = this;\n\n        ARouter.init(this);\n    }\n}\n"
  },
  {
    "path": "layout/src/main/java/me/shouheng/layout/common/NormalTipsFragment.java",
    "content": "package me.shouheng.layout.common;\n\nimport android.app.Activity;\nimport android.os.Bundle;\nimport androidx.annotation.Nullable;\nimport androidx.appcompat.app.ActionBar;\nimport androidx.appcompat.app.AppCompatActivity;\nimport androidx.appcompat.widget.Toolbar;\nimport android.view.View;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.view.fragment.CommonFragment;\nimport me.shouheng.layout.R;\nimport me.shouheng.layout.databinding.FragmentNormalTipsBinding;\n\n/**\n * Created by WngShhng on 2018/6/11.*/\n@Route(path = BaseConstants.LAYOUT_NORMAL_FRAGMENT)\npublic class NormalTipsFragment extends CommonFragment<FragmentNormalTipsBinding> {\n\n    private String title;\n\n    private String content;\n\n    private boolean showToolbar;\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.fragment_normal_tips;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        handleArguments();\n\n        configToolbar();\n\n        configViews();\n    }\n\n    @Override\n    public void onActivityCreated(@Nullable Bundle savedInstanceState) {\n        super.onActivityCreated(savedInstanceState);\n        setHasOptionsMenu(true);\n    }\n\n    private void handleArguments() {\n        Bundle args = getArguments();\n        assert args != null;\n        title = args.getString(BaseConstants.LAYOUT_NORMAL_FRAGMENT_EXTRA_TITLE);\n        content = args.getString(BaseConstants.LAYOUT_NORMAL_FRAGMENT_EXTRA_CONTENT);\n        showToolbar = args.getBoolean(BaseConstants.LAYOUT_NORMAL_FRAGMENT_EXTRA_SHOW_TOOLBAR);\n    }\n\n    private void configToolbar() {\n        Toolbar toolbar = getBinding().barLayout.toolbar;\n        if (!showToolbar) {\n            toolbar.setVisibility(View.GONE);\n            getBinding().shader.setVisibility(View.GONE);\n            return;\n        }\n        Activity activity = getActivity();\n        if (activity != null) {\n            ((AppCompatActivity) activity).setSupportActionBar(toolbar);\n            ActionBar actionBar = ((AppCompatActivity) activity).getSupportActionBar();\n            if (actionBar != null) {\n                actionBar.setTitle(title);\n            }\n        }\n    }\n\n    private void configViews() {\n        getBinding().tvTitle.setText(title);\n        getBinding().tvContent.setText(content);\n    }\n}\n"
  },
  {
    "path": "layout/src/main/java/me/shouheng/layout/view/ActivityEditLayout.java",
    "content": "package me.shouheng.layout.view;\n\nimport android.graphics.Color;\nimport android.graphics.Point;\nimport android.graphics.Rect;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.LinearLayout.LayoutParams;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.ViewUtils;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.layout.R;\nimport me.shouheng.layout.databinding.ActivityEditLayoutBinding;\n\n/**\n * Created on 2018/11/20.\n */\n@Route(path = BaseConstants.LAYOUT_EDIT_LAYOUT)\npublic class ActivityEditLayout extends CommonActivity<ActivityEditLayoutBinding> {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_edit_layout;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        /* Get navigation bar height. */\n        int navHeight = ViewUtils.getNavigationBarHeight(this);\n        int statusBarHeight = ViewUtils.getStatusBarHeight(this);\n\n        /* RootView visible display frame. */\n        Rect visibleRect = new Rect();\n        getWindow().getDecorView().getWindowVisibleDisplayFrame(visibleRect);\n\n        /* LL visible display frame. */\n        Rect llVisibleRect = new Rect();\n        getBinding().ll.getWindowVisibleDisplayFrame(llVisibleRect);\n\n        /* Get window information. */\n        Point p = ViewUtils.getWindowSize(this);\n\n        /* Add a view with the same height of status bar. */\n        View view = new View(this);\n        view.setBackgroundColor(Color.BLUE);\n        LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, statusBarHeight);\n        view.setLayoutParams(lp);\n        getBinding().container.addView(view, 0);\n\n        new Handler().postDelayed(() -> {\n            /* Get the ll hit rectangle. */\n            Rect llHitRect = new Rect();\n            getBinding().ll.getHitRect(llHitRect);\n\n            /* RootView visible display frame. */\n            Rect rootHitRect = new Rect();\n            getWindow().getDecorView().getHitRect(rootHitRect);\n\n            /* Display information. */\n            getBinding().tvInfo.setText(\"DecorView HitRect : \" + rootHitRect + \"\\n\"\n                    + \"DecorView VisibleRect : \" +  visibleRect + \"\\n\"\n                    + \"Screen : \" + p + \"\\n\"\n                    + \"LL HitRect : \" + llHitRect + \"\\n\"\n                    + \"LL VisibleRect : \" + llVisibleRect + \"\\n\"\n                    + \"StatusBar :\" + statusBarHeight + \"\\n\"\n                    + \"NavBar :\" + navHeight + \"\\n\"\n                    + \"LL(x:\" + getBinding().ll.getX() + \", \" + \"y:\" + getBinding().ll.getY() + \",\" + \"w:\" + getBinding().ll.getWidth() + \",\" + \"h:\" + getBinding().ll.getHeight() + \") \\n\"\n                    + \"V(x:\" + getBinding().v.getX() + \", \" + \"y:\" + getBinding().v.getY() + \",\" + \"w:\" + getBinding().v.getWidth() + \",\" + \"h:\" + getBinding().v.getHeight() + \") \\n\");\n        }, 100);\n    }\n}\n"
  },
  {
    "path": "layout/src/main/java/me/shouheng/layout/view/DrawerActivity.java",
    "content": "package me.shouheng.layout.view;\n\nimport android.os.Bundle;\nimport com.google.android.material.floatingactionbutton.FloatingActionButton;\nimport com.google.android.material.navigation.NavigationView;\nimport com.google.android.material.snackbar.Snackbar;\nimport androidx.core.view.GravityCompat;\nimport androidx.drawerlayout.widget.DrawerLayout;\nimport androidx.appcompat.app.ActionBarDrawerToggle;\nimport androidx.appcompat.app.AppCompatActivity;\nimport androidx.appcompat.widget.Toolbar;\nimport android.view.Menu;\nimport android.view.MenuItem;\nimport android.view.View;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.layout.R;\n\n@Route(path = BaseConstants.LAYOUT_DRAWER)\npublic class DrawerActivity extends AppCompatActivity\n        implements NavigationView.OnNavigationItemSelectedListener {\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_drawer);\n        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);\n        setSupportActionBar(toolbar);\n\n        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);\n        fab.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                Snackbar.make(view, \"Replace with your own action\", Snackbar.LENGTH_LONG)\n                        .setAction(\"Action\", null).show();\n            }\n        });\n\n        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);\n        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(\n                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);\n        drawer.addDrawerListener(toggle);\n        toggle.syncState();\n\n        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);\n        navigationView.setNavigationItemSelectedListener(this);\n    }\n\n    @Override\n    public void onBackPressed() {\n        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);\n        if (drawer.isDrawerOpen(GravityCompat.START)) {\n            drawer.closeDrawer(GravityCompat.START);\n        } else {\n            super.onBackPressed();\n        }\n    }\n\n    @Override\n    public boolean onCreateOptionsMenu(Menu menu) {\n        // Inflate the menu; this adds items to the action bar if it is present.\n        getMenuInflater().inflate(R.menu.drawer, menu);\n        return true;\n    }\n\n    @Override\n    public boolean onOptionsItemSelected(MenuItem item) {\n        // Handle action bar item clicks here. The action bar will\n        // automatically handle clicks on the Home/Up button, so long\n        // as you specify a parent activity in AndroidManifest.xml.\n        int id = item.getItemId();\n\n        //noinspection SimplifiableIfStatement\n        if (id == R.id.action_settings) {\n            return true;\n        }\n\n        return super.onOptionsItemSelected(item);\n    }\n\n    @SuppressWarnings(\"StatementWithEmptyBody\")\n    @Override\n    public boolean onNavigationItemSelected(MenuItem item) {\n        // Handle navigation view item clicks here.\n        int id = item.getItemId();\n\n        if (id == R.id.nav_camera) {\n            // Handle the camera action\n        } else if (id == R.id.nav_gallery) {\n\n        } else if (id == R.id.nav_slideshow) {\n\n        } else if (id == R.id.nav_manage) {\n\n        } else if (id == R.id.nav_share) {\n\n        } else if (id == R.id.nav_send) {\n\n        }\n\n        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);\n        drawer.closeDrawer(GravityCompat.START);\n        return true;\n    }\n}\n"
  },
  {
    "path": "layout/src/main/java/me/shouheng/layout/view/LayoutMenuActivity.java",
    "content": "package me.shouheng.layout.view;\n\nimport android.os.Bundle;\nimport androidx.appcompat.app.ActionBar;\nimport androidx.appcompat.widget.Toolbar;\nimport android.view.MenuItem;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.alibaba.android.arouter.launcher.ARouter;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.layout.R;\nimport me.shouheng.layout.databinding.ActivityLayoutMenuBinding;\n\n@Route(path = BaseConstants.LAYOUT_MENU)\npublic class LayoutMenuActivity extends CommonActivity<ActivityLayoutMenuBinding> {\n\n    private boolean useAdapter = true;\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_layout_menu;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        configToolbar();\n\n        getBinding().bntNav.setOnClickListener(v ->\n                ARouter.getInstance()\n                        .build(BaseConstants.LAYOUT_NAVIGATION)\n                        .navigation());\n        getBinding().bntTabbed.setOnClickListener(v ->\n                ARouter.getInstance()\n                        .build(BaseConstants.LAYOUT_TABBED)\n                        .navigation());\n        getBinding().bntBottomSheet.setOnClickListener(v ->\n                ARouter.getInstance()\n                        .build(BaseConstants.LAYOUT_BOTTOM_SHEET)\n                        .navigation());\n        getBinding().bntCollapse.setOnClickListener(v ->\n                ARouter.getInstance()\n                        .build(BaseConstants.LAYOUT_COLLAPSE_BAR)\n                        .navigation());\n        getBinding().bntScrolling.setOnClickListener(v ->\n                ARouter.getInstance()\n                        .build(BaseConstants.LAYOUT_SCROLLING)\n                        .navigation());\n        getBinding().btnDrawer.setOnClickListener(v ->\n                ARouter.getInstance()\n                        .build(BaseConstants.LAYOUT_DRAWER)\n                        .navigation());\n        getBinding().btnViewSystem.setOnClickListener(v ->\n                ARouter.getInstance()\n                        .build(BaseConstants.LAYOUT_VIEW_SYSTEM)\n                        .navigation());\n        getBinding().btnViewAnimate.setOnClickListener(v ->\n                ARouter.getInstance()\n                        .build(BaseConstants.LAYOUT_VIEW_ANIMATE)\n                        .navigation());\n        getBinding().bntSupport28.setOnClickListener(v ->\n                ARouter.getInstance()\n                        .build(BaseConstants.LAYOUT_SUPPORT_28)\n                        .navigation());\n        getBinding().btnSwipe.setOnClickListener(v ->\n                ARouter.getInstance()\n                        .build(BaseConstants.LAYOUT_SWIPE_BACK)\n                        .navigation());\n        getBinding().btnAdapter.setOnClickListener(v ->\n                ARouter.getInstance()\n                        .build(BaseConstants.LAYOUT_ADAPTER)\n                        .withBoolean(BaseConstants.LAYOUT_ADAPTER_ARG_USE_ADAPTER, useAdapter = !useAdapter)\n                        .navigation());\n        getBinding().btnEdit.setOnClickListener(v ->\n                ARouter.getInstance()\n                        .build(BaseConstants.LAYOUT_EDIT_LAYOUT)\n                        .navigation());\n    }\n\n    private void configToolbar() {\n        Toolbar toolbar = getBinding().barLayout.toolbar;\n        toolbar.setBackgroundResource(R.color.light_theme_background);\n        setSupportActionBar(toolbar);\n        ActionBar actionBar = getSupportActionBar();\n        if (actionBar != null) {\n            actionBar.setTitle(R.string.menu_item_title_3);\n            actionBar.setSubtitle(R.string.menu_item_desc_3);\n            actionBar.setDisplayHomeAsUpEnabled(true);\n        }\n    }\n\n    @Override\n    public boolean onOptionsItemSelected(MenuItem item) {\n        switch (item.getItemId()) {\n            case android.R.id.home:\n                super.onBackPressed();\n                break;\n        }\n        return super.onOptionsItemSelected(item);\n    }\n}\n"
  },
  {
    "path": "layout/src/main/java/me/shouheng/layout/view/adapter/AdapterUtils.java",
    "content": "package me.shouheng.layout.view.adapter;\n\nimport android.app.Activity;\nimport android.app.Application;\nimport android.content.ComponentCallbacks;\nimport android.content.res.Configuration;\nimport android.util.DisplayMetrics;\n\n/**\n * Created by WngShhng on 2018/10/29.\n */\npublic class AdapterUtils {\n\n    private static float noCompactDensity;\n\n    private static float noCompactScaledDensity;\n\n    public static void setCustomDensity(Activity activity, Application application) {\n        DisplayMetrics appDisplayMetrics = application.getResources().getDisplayMetrics();\n\n        if (noCompactDensity == 0) {\n            noCompactDensity = appDisplayMetrics.density;\n            noCompactScaledDensity = appDisplayMetrics.scaledDensity;\n            application.registerComponentCallbacks(new ComponentCallbacks() {\n                @Override\n                public void onConfigurationChanged(Configuration newConfig) {\n                    if (newConfig != null && newConfig.fontScale > 0) {\n                        noCompactScaledDensity = application.getResources().getDisplayMetrics().scaledDensity;\n                    }\n                }\n\n                @Override\n                public void onLowMemory() { }\n            });\n        }\n\n        float targetDensity = appDisplayMetrics.widthPixels / 360;\n        float targetScaledDensity = targetDensity * (noCompactScaledDensity / noCompactDensity);\n        int targetDensityDpi = (int) (160 * targetDensity);\n\n        appDisplayMetrics.density = targetDensity;\n        appDisplayMetrics.scaledDensity = targetScaledDensity;\n        appDisplayMetrics.densityDpi = targetDensityDpi;\n\n        DisplayMetrics activityDisplayMetrics = activity.getResources().getDisplayMetrics();\n        activityDisplayMetrics.density = targetDensity;\n        activityDisplayMetrics.scaledDensity = targetScaledDensity;\n        activityDisplayMetrics.densityDpi = targetDensityDpi;\n    }\n}\n"
  },
  {
    "path": "layout/src/main/java/me/shouheng/layout/view/adapter/BeforeAdapter.java",
    "content": "package me.shouheng.layout.view.adapter;\n\nimport android.os.Bundle;\nimport androidx.appcompat.app.AlertDialog;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.LogUtils;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.layout.R;\nimport me.shouheng.layout.databinding.ActivityAdapterBinding;\n\n/**\n * Created by WngShhng on 2018/10/29.\n */\n@Route(path = BaseConstants.LAYOUT_ADAPTER)\npublic class BeforeAdapter extends CommonActivity<ActivityAdapterBinding> {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_adapter;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        boolean useAdapter = getIntent().getBooleanExtra(BaseConstants.LAYOUT_ADAPTER_ARG_USE_ADAPTER, false);\n        LogUtils.d(\"should use screen adapter \" + useAdapter);\n        if (useAdapter) {\n            AdapterUtils.setCustomDensity(this, getApplication());\n        }\n\n        new AlertDialog.Builder(this)\n                .setTitle(\"测试对话框\")\n                .setMessage(\"用来测试布局适配性的对话框\")\n                .create().show();\n    }\n}\n"
  },
  {
    "path": "layout/src/main/java/me/shouheng/layout/view/bottomsheet/BottomSheetActivity.java",
    "content": "package me.shouheng.layout.view.bottomsheet;\n\nimport android.graphics.Color;\nimport android.os.Bundle;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.layout.R;\nimport me.shouheng.layout.databinding.ActivityBottomSheetBinding;\n\n@Route(path = BaseConstants.LAYOUT_BOTTOM_SHEET)\npublic class BottomSheetActivity extends CommonActivity<ActivityBottomSheetBinding> {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_bottom_sheet;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        getBinding().toolbar.setTitle(R.string.menu_item_sub_title_3);\n        getBinding().toolbar.setTitleTextColor(Color.BLACK);\n    }\n}\n"
  },
  {
    "path": "layout/src/main/java/me/shouheng/layout/view/collapse/CollapseBarStructure.java",
    "content": "package me.shouheng.layout.view.collapse;\n\nimport android.graphics.Color;\nimport android.os.Bundle;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.layout.R;\nimport me.shouheng.layout.databinding.ActivityCollapseBarStructureBinding;\n\n@Route(path = BaseConstants.LAYOUT_COLLAPSE_BAR)\npublic class CollapseBarStructure extends CommonActivity<ActivityCollapseBarStructureBinding> {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_collapse_bar_structure;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        getBinding().toolbar.setTitle(\"\");\n        getBinding().toolbar.setTitleTextColor(Color.BLACK);\n    }\n}\n"
  },
  {
    "path": "layout/src/main/java/me/shouheng/layout/view/custom/CustomView.java",
    "content": "package me.shouheng.layout.view.custom;\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport androidx.annotation.Nullable;\nimport android.util.AttributeSet;\nimport android.view.View;\n\n/**\n * @author shouh\n * @version $Id: CustomView, v 0.1 2018/10/13 11:31 shouh Exp$\n */\npublic class CustomView extends View {\n\n    public CustomView(Context context) {\n        super(context);\n    }\n\n    public CustomView(Context context, @Nullable AttributeSet attrs) {\n        super(context, attrs);\n    }\n\n    public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {\n        super(context, attrs, defStyleAttr);\n    }\n\n    @Override\n    protected void onDraw(Canvas canvas) {\n        super.onDraw(canvas);\n    }\n\n    @Override\n    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {\n        super.onLayout(changed, left, top, right, bottom);\n    }\n\n    @Override\n    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {\n        super.onMeasure(widthMeasureSpec, heightMeasureSpec);\n    }\n}\n"
  },
  {
    "path": "layout/src/main/java/me/shouheng/layout/view/navigation/NavigationActivity.java",
    "content": "package me.shouheng.layout.view.navigation;\n\nimport android.os.Bundle;\nimport androidx.fragment.app.FragmentManager;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.alibaba.android.arouter.launcher.ARouter;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.PalmUtils;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.layout.R;\nimport me.shouheng.layout.common.NormalTipsFragment;\nimport me.shouheng.layout.databinding.ActivityNavigationBinding;\nimport me.shouheng.layout.view.navigation.fragment.PagerFragment;\n\n@Route(path = BaseConstants.LAYOUT_NAVIGATION)\npublic class NavigationActivity extends CommonActivity<ActivityNavigationBinding> {\n\n    private final String FRAGMENT_KEY_PAGER = \"__key_fragment_pager\";\n    private final String FRAGMENT_KEY_FAVORITE = \"__key_fragment_favorite\";\n    private final String FRAGMENT_KEY_INFO = \"__key_fragment_info\";\n\n    private PagerFragment pagerFragment;\n    private NormalTipsFragment favoriteFragment;\n    private NormalTipsFragment infoFragment;\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_navigation;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        initFragments(savedInstanceState);\n\n        getBinding().nav.setOnNavigationItemSelectedListener(menuItem -> {\n            if (menuItem.getItemId() == R.id.nav_main) {\n                showFragment(FRAGMENT_KEY_PAGER);\n            } else if (menuItem.getItemId() == R.id.nav_favorite) {\n                showFragment(FRAGMENT_KEY_FAVORITE);\n            } else if (menuItem.getItemId() == R.id.nav_info) {\n                showFragment(FRAGMENT_KEY_INFO);\n            }\n            return true;\n        });\n\n        showFragment(FRAGMENT_KEY_PAGER);\n    }\n\n    private void initFragments(Bundle savedInstanceState) {\n        FragmentManager fm = getSupportFragmentManager();\n        if (savedInstanceState == null) {\n            pagerFragment = (PagerFragment) ARouter.getInstance()\n                    .build(BaseConstants.LAYOUT_PAGER_FRAGMENT)\n                    .navigation();\n            favoriteFragment = (NormalTipsFragment) ARouter.getInstance()\n                    .build(BaseConstants.LAYOUT_NORMAL_FRAGMENT)\n                    .withString(BaseConstants.LAYOUT_NORMAL_FRAGMENT_EXTRA_TITLE, PalmUtils.getStringCompact(R.string.nav_bottom_item_2))\n                    .withString(BaseConstants.LAYOUT_NORMAL_FRAGMENT_EXTRA_CONTENT, PalmUtils.getStringCompact(R.string.nav_bottom_desc_2))\n                    .withBoolean(BaseConstants.LAYOUT_NORMAL_FRAGMENT_EXTRA_SHOW_TOOLBAR, true)\n                    .navigation();\n            infoFragment = (NormalTipsFragment) ARouter.getInstance()\n                    .build(BaseConstants.LAYOUT_NORMAL_FRAGMENT)\n                    .withString(BaseConstants.LAYOUT_NORMAL_FRAGMENT_EXTRA_TITLE, PalmUtils.getStringCompact(R.string.nav_bottom_item_3))\n                    .withString(BaseConstants.LAYOUT_NORMAL_FRAGMENT_EXTRA_CONTENT, PalmUtils.getStringCompact(R.string.nav_bottom_desc_3))\n                    .withBoolean(BaseConstants.LAYOUT_NORMAL_FRAGMENT_EXTRA_SHOW_TOOLBAR, true)\n                    .navigation();\n        } else {\n            pagerFragment = (PagerFragment) fm.getFragment(savedInstanceState, FRAGMENT_KEY_PAGER);\n            favoriteFragment = (NormalTipsFragment) fm.getFragment(savedInstanceState, FRAGMENT_KEY_FAVORITE);\n            infoFragment = (NormalTipsFragment) fm.getFragment(savedInstanceState, FRAGMENT_KEY_INFO);\n        }\n\n        if (!pagerFragment.isAdded()) {\n            fm.beginTransaction().add(R.id.fragment_container, pagerFragment, FRAGMENT_KEY_PAGER).commit();\n        }\n        if (!favoriteFragment.isAdded()) {\n            fm.beginTransaction().add(R.id.fragment_container, favoriteFragment, FRAGMENT_KEY_FAVORITE).commit();\n        }\n        if (!infoFragment.isAdded()) {\n            fm.beginTransaction().add(R.id.fragment_container, infoFragment, FRAGMENT_KEY_INFO).commit();\n        }\n    }\n\n    private void showFragment(String key) {\n        FragmentManager fm = getSupportFragmentManager();\n        switch (key) {\n            case FRAGMENT_KEY_PAGER:\n                fm.beginTransaction().show(pagerFragment).hide(favoriteFragment).hide(infoFragment).commit();\n                break;\n            case FRAGMENT_KEY_FAVORITE:\n                fm.beginTransaction().show(favoriteFragment).hide(pagerFragment).hide(infoFragment).commit();\n                break;\n            case FRAGMENT_KEY_INFO:\n                fm.beginTransaction().show(infoFragment).hide(favoriteFragment).hide(pagerFragment).commit();\n                break;\n        }\n    }\n}\n"
  },
  {
    "path": "layout/src/main/java/me/shouheng/layout/view/navigation/fragment/PagerFragment.java",
    "content": "package me.shouheng.layout.view.navigation.fragment;\n\nimport android.graphics.Color;\nimport android.os.Bundle;\nimport androidx.annotation.Nullable;\nimport com.google.android.material.tabs.TabLayout.OnTabSelectedListener;\nimport com.google.android.material.tabs.TabLayout.Tab;\nimport androidx.fragment.app.Fragment;\nimport androidx.fragment.app.FragmentManager;\nimport androidx.fragment.app.FragmentPagerAdapter;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.alibaba.android.arouter.launcher.ARouter;\n\nimport java.util.Arrays;\nimport java.util.List;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.ToastUtils;\nimport me.shouheng.commons.view.fragment.CommonFragment;\nimport me.shouheng.layout.R;\nimport me.shouheng.layout.common.NormalTipsFragment;\nimport me.shouheng.layout.databinding.FragmentPagerBinding;\n\n/**\n * Created by WngShhng on 2018/6/11.*/\n@Route(path = BaseConstants.LAYOUT_PAGER_FRAGMENT)\npublic class PagerFragment extends CommonFragment<FragmentPagerBinding> {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.fragment_pager;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        getBinding().toolbar.setTitle(R.string.menu_item_sub_title_1);\n        getBinding().toolbar.setTitleTextColor(Color.BLACK);\n\n        Fragment tabFragment1 = (NormalTipsFragment) ARouter.getInstance()\n                .build(BaseConstants.LAYOUT_NORMAL_FRAGMENT)\n                .withString(BaseConstants.LAYOUT_NORMAL_FRAGMENT_EXTRA_TITLE, \"Tab Fragment 1\")\n                .withString(BaseConstants.LAYOUT_NORMAL_FRAGMENT_EXTRA_CONTENT, \"This is the content for the tab fragment 1\")\n                .withBoolean(BaseConstants.LAYOUT_NORMAL_FRAGMENT_EXTRA_SHOW_TOOLBAR, false)\n                .navigation();\n        Fragment tabFragment2 = (NormalTipsFragment) ARouter.getInstance()\n                .build(BaseConstants.LAYOUT_NORMAL_FRAGMENT)\n                .withString(BaseConstants.LAYOUT_NORMAL_FRAGMENT_EXTRA_TITLE, \"Tab Fragment 2\")\n                .withString(BaseConstants.LAYOUT_NORMAL_FRAGMENT_EXTRA_CONTENT, \"This is the content for the tab fragment 2\")\n                .withBoolean(BaseConstants.LAYOUT_NORMAL_FRAGMENT_EXTRA_SHOW_TOOLBAR, false)\n                .navigation();\n        Fragment tabFragment3 = (NormalTipsFragment) ARouter.getInstance()\n                .build(BaseConstants.LAYOUT_NORMAL_FRAGMENT)\n                .withString(BaseConstants.LAYOUT_NORMAL_FRAGMENT_EXTRA_TITLE, \"Tab Fragment 3\")\n                .withString(BaseConstants.LAYOUT_NORMAL_FRAGMENT_EXTRA_CONTENT, \"This is the content for the tab fragment 3\")\n                .withBoolean(BaseConstants.LAYOUT_NORMAL_FRAGMENT_EXTRA_SHOW_TOOLBAR, false)\n                .navigation();\n\n        getBinding().vp.setAdapter(new TabFragmentAdapter(getFragmentManager(),\n                Arrays.asList(tabFragment1, tabFragment2, tabFragment3),\n                Arrays.asList(\"Tab1\", \"Tab2\", \"Tab3\")));\n        getBinding().vp.setOffscreenPageLimit(3);\n        getBinding().tabLayout.setupWithViewPager(getBinding().vp);\n        getBinding().tabLayout.addOnTabSelectedListener(new OnTabSelectedListener() {\n            @Override\n            public void onTabSelected(Tab tab) {\n                ToastUtils.makeToast(\"Tab\" + (1 + tab.getPosition()) + \"clicked!\");\n            }\n\n            @Override\n            public void onTabUnselected(Tab tab) { }\n\n            @Override\n            public void onTabReselected(Tab tab) { }\n        });\n\n        getBinding().fab.setOnClickListener(v -> ToastUtils.makeToast(\"Fab clicked!\"));\n    }\n\n    public static class TabFragmentAdapter extends FragmentPagerAdapter {\n\n        private List<Fragment> fragments;\n\n        private List<String> titles;\n\n        TabFragmentAdapter(FragmentManager fm, List<Fragment> fragments, List<String> titles) {\n            super(fm);\n            this.fragments = fragments;\n            this.titles = titles;\n            if (fragments.size() - titles.size() != 0) {\n                throw new IllegalArgumentException(\"The length for fragments and titles must be the same!\");\n            }\n        }\n\n        @Override\n        public Fragment getItem(int position) {\n            return fragments.get(position);\n        }\n\n        @Override\n        public int getCount() {\n            return fragments.size();\n        }\n\n        @Nullable\n        @Override\n        public CharSequence getPageTitle(int position) {\n            return titles.get(position);\n        }\n    }\n}\n"
  },
  {
    "path": "layout/src/main/java/me/shouheng/layout/view/scrolling/ScrollingActivity.java",
    "content": "package me.shouheng.layout.view.scrolling;\n\nimport android.graphics.Color;\nimport android.os.Bundle;\nimport com.google.android.material.snackbar.Snackbar;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.layout.R;\nimport me.shouheng.layout.databinding.ActivityScrollingBinding;\n\n@Route(path = BaseConstants.LAYOUT_SCROLLING)\npublic class ScrollingActivity extends CommonActivity<ActivityScrollingBinding> {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_scrolling;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        getBinding().toolbar.setTitle(R.string.menu_item_sub_title_4);\n        getBinding().toolbar.setTitleTextColor(Color.BLACK);\n\n        getBinding().fab.setOnClickListener(v ->\n                Snackbar.make(v, \"Replace with your own action\", Snackbar.LENGTH_LONG)\n                        .setAction(\"Action\", null).show());\n    }\n}\n"
  },
  {
    "path": "layout/src/main/java/me/shouheng/layout/view/support28/BottomAppBarActivity.java",
    "content": "package me.shouheng.layout.view.support28;\n\nimport android.os.Bundle;\nimport androidx.annotation.Nullable;\nimport androidx.recyclerview.widget.LinearLayoutManager;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.chad.library.adapter.base.BaseQuickAdapter;\nimport com.chad.library.adapter.base.BaseViewHolder;\n\nimport java.util.LinkedList;\nimport java.util.List;\n\nimport io.reactivex.Observable;\nimport io.reactivex.disposables.Disposable;\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.layout.R;\nimport me.shouheng.layout.databinding.ActivityBottomAppBarBinding;\n\n/**\n * Created by WngShhng on 2018/9/11.\n */\n@Route(path = BaseConstants.LAYOUT_BOTTOM_APP_BAR)\npublic class BottomAppBarActivity extends CommonActivity<ActivityBottomAppBarBinding> {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_bottom_app_bar;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n//        getBinding().bottomAppBar.replaceMenu(R.menu.bottom_navigation);\n//\n        List<String> items = new LinkedList<>();\n        Disposable disposable = Observable.range(40, 50).subscribe(integer -> items.add(String.valueOf(integer)));\n        Adapter adapter = new Adapter(items);\n        getBinding().rv.setLayoutManager(new LinearLayoutManager(getContext()));\n        getBinding().rv.setAdapter(adapter);\n    }\n\n    private static class Adapter extends BaseQuickAdapter<String, BaseViewHolder> {\n\n        Adapter(@Nullable List<String> data) {\n            super(android.R.layout.simple_list_item_1, data);\n        }\n\n        @Override\n        protected void convert(BaseViewHolder helper, String item) {\n            helper.setText(android.R.id.text1, item);\n        }\n    }\n}\n"
  },
  {
    "path": "layout/src/main/java/me/shouheng/layout/view/support28/Support28Activity.java",
    "content": "package me.shouheng.layout.view.support28;\n\nimport android.os.Bundle;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.alibaba.android.arouter.launcher.ARouter;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.layout.R;\nimport me.shouheng.layout.databinding.ActivitySupport28Binding;\n\n/**\n * Created by WngShhng on 2018/9/11.\n */\n@Route(path = BaseConstants.LAYOUT_SUPPORT_28)\npublic class Support28Activity extends CommonActivity<ActivitySupport28Binding> {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_support_28;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        getBinding().btnBottomBar.setOnClickListener(v ->\n                ARouter.getInstance()\n                        .build(BaseConstants.LAYOUT_BOTTOM_APP_BAR)\n                        .navigation());\n    }\n}\n"
  },
  {
    "path": "layout/src/main/java/me/shouheng/layout/view/swipe/SwipeBackDemoActivity.java",
    "content": "package me.shouheng.layout.view.swipe;\n\nimport android.os.Bundle;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n\nimport me.imid.swipebacklayout.lib.app.SwipeBackActivity;\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.layout.R;\n\n/**\n * Created by WngShhng on 2018/10/19.\n */\n@Route(path = BaseConstants.LAYOUT_SWIPE_BACK)\npublic class SwipeBackDemoActivity extends SwipeBackActivity {\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_swipe_back);\n    }\n}\n"
  },
  {
    "path": "layout/src/main/java/me/shouheng/layout/view/tabbed/TabbedActivity.java",
    "content": "package me.shouheng.layout.view.tabbed;\n\nimport android.graphics.Color;\nimport android.os.Bundle;\nimport com.google.android.material.snackbar.Snackbar;\nimport androidx.fragment.app.Fragment;\nimport androidx.fragment.app.FragmentManager;\nimport androidx.fragment.app.FragmentPagerAdapter;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.alibaba.android.arouter.launcher.ARouter;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.layout.R;\nimport me.shouheng.layout.databinding.ActivityTabbedBinding;\n\n@Route(path = BaseConstants.LAYOUT_TABBED)\npublic class TabbedActivity extends CommonActivity<ActivityTabbedBinding> {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_tabbed;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        getBinding().toolbar.setTitle(R.string.menu_item_sub_title_2);\n        getBinding().toolbar.setTitleTextColor(Color.BLACK);\n        setSupportActionBar(getBinding().toolbar);\n\n        SectionsPagerAdapter adapter = new SectionsPagerAdapter(getSupportFragmentManager());\n        getBinding().vp.setAdapter(adapter);\n\n        getBinding().fab.setOnClickListener(view ->\n                Snackbar.make(view, \"Fab is clicked!\", Snackbar.LENGTH_LONG)\n                        .setAction(\"Action\", null).show()\n        );\n    }\n\n    public class SectionsPagerAdapter extends FragmentPagerAdapter {\n\n        SectionsPagerAdapter(FragmentManager fm) {\n            super(fm);\n        }\n\n        @Override\n        public Fragment getItem(int position) {\n            return (Fragment) ARouter.getInstance()\n                    .build(BaseConstants.LAYOUT_NORMAL_FRAGMENT)\n                    .withString(BaseConstants.LAYOUT_NORMAL_FRAGMENT_EXTRA_TITLE, \"Fragment \" + (position + 1))\n                    .withString(BaseConstants.LAYOUT_NORMAL_FRAGMENT_EXTRA_CONTENT, \"Content fragment of tabbed activity : \" + (position + 1))\n                    .withBoolean(BaseConstants.LAYOUT_NORMAL_FRAGMENT_EXTRA_SHOW_TOOLBAR, false)\n                    .navigation();\n        }\n\n        @Override\n        public int getCount() {\n            return 3;\n        }\n\n        @Override\n        public CharSequence getPageTitle(int position) {\n            switch (position) {\n                case 0: return \"Tab 1\";\n                case 1: return \"Tab 2\";\n                case 2: return \"Tab 3\";\n            }\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "layout/src/main/java/me/shouheng/layout/view/views/CustomView.java",
    "content": "package me.shouheng.layout.view.views;\n\nimport android.content.Context;\nimport androidx.annotation.Nullable;\nimport android.util.AttributeSet;\nimport android.view.View;\nimport android.widget.Scroller;\n\n/**\n * @author shouh\n * @version $Id: CustomView, v 0.1 2018/10/5 16:34 shouh Exp$\n */\npublic class CustomView extends View {\n\n    private Scroller scroller = new Scroller(getContext());\n\n    public CustomView(Context context) {\n        super(context);\n    }\n\n    public CustomView(Context context, @Nullable AttributeSet attrs) {\n        super(context, attrs);\n    }\n\n    public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {\n        super(context, attrs, defStyleAttr);\n    }\n\n    @Override\n    public void computeScroll() {\n        super.computeScroll();\n        if (scroller.computeScrollOffset()) {\n            ((View) getParent()).scrollTo(scroller.getCurrX(), scroller.getCurrY());\n            invalidate();\n        }\n    }\n\n    public void smoothScrollTo(int descX, int descY) {\n        scroller.startScroll(getScrollX(), getScrollY(), descX - getScrollX(), descY - getScrollY(), 2000);\n        invalidate();\n    }\n}\n"
  },
  {
    "path": "layout/src/main/java/me/shouheng/layout/view/views/ViewAnimateActivity.java",
    "content": "package me.shouheng.layout.view.views;\n\nimport android.animation.TypeEvaluator;\nimport android.animation.ValueAnimator;\nimport android.graphics.drawable.AnimationDrawable;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.transition.Explode;\nimport android.view.animation.AnimationUtils;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n\nimport java.util.Date;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.LogUtils;\nimport me.shouheng.commons.tools.ToastUtils;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.layout.R;\nimport me.shouheng.layout.databinding.ActivityViewAnimateBinding;\n\n/**\n * @author shouh\n * @version $Id: ViewAnimateActivity, v 0.1 2018/10/5 18:41 shouh Exp$\n */\n@Route(path = BaseConstants.LAYOUT_VIEW_ANIMATE)\npublic class ViewAnimateActivity extends CommonActivity<ActivityViewAnimateBinding> {\n\n    private AnimationDrawable animDraw;\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_view_animate;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {\n            getWindow().setEnterTransition(new Explode());\n        } else {\n            overridePendingTransition(R.anim.shake, R.anim.shake);\n        }\n\n        getBinding().v.setOnClickListener(v -> ToastUtils.makeToast(\"Clicked\"));\n        getBinding().btnAniamte.setOnClickListener(v -> animate());\n        getBinding().btnShake.setOnClickListener(v -> shake());\n\n        // Drawable 动画\n        getBinding().ivRecord.setImageResource(R.drawable.record_anim);\n        animDraw = (AnimationDrawable) getBinding().ivRecord.getDrawable();\n        animDraw.start();\n\n        ValueAnimator animator = ValueAnimator.ofObject(new DateEvaluator(), new Date(0), new Date());\n        animator.setDuration(5000);\n        animator.addUpdateListener(animation -> {\n            Date date = (Date) animation.getAnimatedValue();\n            LogUtils.d(date);\n        });\n        animator.start();\n    }\n\n    private static class DateEvaluator implements TypeEvaluator<Date> {\n\n        @Override\n        public Date evaluate(float fraction, Date startValue, Date endValue) {\n            long startTime = startValue.getTime();\n            return new Date((long) (startTime + fraction * (endValue.getTime() - startTime)));\n        }\n    }\n\n    private void animate() {\n        getBinding().v.animate()\n                .scaleY(0.5f)\n                .scaleX(0.5f)\n                .translationX(100)\n                .translationX(100)\n                .rotation(5f)\n                .start();\n    }\n\n    private void shake() {\n        getBinding().v.startAnimation(AnimationUtils.loadAnimation(this, R.anim.shake));\n    }\n\n    @Override\n    protected void onPause() {\n        super.onPause();\n        animDraw.stop();\n    }\n}\n"
  },
  {
    "path": "layout/src/main/java/me/shouheng/layout/view/views/ViewSystemActivity.java",
    "content": "package me.shouheng.layout.view.views;\n\nimport android.annotation.SuppressLint;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.view.GestureDetector;\nimport android.view.MotionEvent;\nimport android.view.VelocityTracker;\nimport android.view.View;\nimport android.widget.FrameLayout;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.LogUtils;\nimport me.shouheng.commons.tools.ToastUtils;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.layout.R;\nimport me.shouheng.layout.databinding.ActivityViewSystemBinding;\n\n/**\n * @author shouh\n * @version $Id: ViewSystemActivity, v 0.1 2018/10/5 13:24 shouh Exp$\n */\n@Route(path = BaseConstants.LAYOUT_VIEW_SYSTEM)\npublic class ViewSystemActivity extends CommonActivity<ActivityViewSystemBinding> {\n\n    private int lastX, lastY;\n\n    private GestureDetector mGestureDetector;\n    private VelocityTracker velocityTracker;\n    private long duration, downTime;\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_view_system;\n    }\n\n    @SuppressLint(\"ClickableViewAccessibility\")\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        dispCoordinate(null);\n        getBinding().v.setOnTouchListener((v, event) -> {\n            dispCoordinate(event);\n//            layoutMove(event);\n//            offsetMove(event);\n//            lpMove(event);\n//            scrollByMove(event);\n            scrollToMove(event);\n            return true;\n        });\n        getBinding().btnTrans.setOnClickListener(v -> {\n            getBinding().v.animate().translationX(5f);\n            getBinding().v.animate().translationY(5f);\n            dispCoordinate(null);\n        });\n        getBinding().btnScroller.setOnClickListener(v -> scrollerMove());\n        new Handler().postDelayed(() -> dispCoordinate(null), 1000);\n\n        // GestureDetector\n        mGestureDetector = new GestureDetector(getContext(), new MyOnGestureListener());\n        velocityTracker = VelocityTracker.obtain();\n\n        getBinding().vg.setOnTouchListener((v, event) -> {\n            mGestureDetector.onTouchEvent(event);\n            velocityTracker.addMovement(event);\n            switch (event.getAction()) {\n                case MotionEvent.ACTION_DOWN:\n                    downTime = System.currentTimeMillis();\n                    break;\n                case MotionEvent.ACTION_UP:\n                    duration = System.currentTimeMillis() - downTime;\n                    break;\n            }\n            return true;\n        });\n        getBinding().btnVelocity.setOnClickListener(v -> {\n            velocityTracker.computeCurrentVelocity((int) duration);\n            getBinding().tvVelocity.setText(\"X:\" + velocityTracker.getXVelocity() + \"\\n\"\n                    + \"Y:\" + velocityTracker.getYVelocity());\n        });\n    }\n\n    private class MyOnGestureListener extends GestureDetector.SimpleOnGestureListener {\n\n        @Override\n        public boolean onSingleTapUp(MotionEvent e) {\n            ToastUtils.makeToast(\"Click detected\");\n            return false;\n        }\n\n        @Override\n        public void onLongPress(MotionEvent e) {\n            LogUtils.d(\"Long press detected\");\n        }\n\n        @Override\n        public boolean onDoubleTap(MotionEvent e) {\n            LogUtils.d(\"Double tab detected\");\n            return true;\n        }\n\n        @Override\n        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {\n            LogUtils.d(\"Fling detected\");\n            return true;\n        }\n    }\n\n    private void dispCoordinate(MotionEvent event) {\n        String coordinate = \"View.Top:\" + getBinding().v.getTop() + \"\\n\"\n                + \"View.Bottom:\" + getBinding().v.getBottom() + \"\\n\"\n                + \"View.Left:\" + getBinding().v.getLeft() + \"\\n\"\n                + \"View.Right:\" + getBinding().v.getRight() + \"\\n\"\n                + \"View.X:\" + getBinding().v.getX() + \"\\n\"\n                + \"View.Y:\" + getBinding().v.getY() + \"\\n\"\n                + \"View.Height:\" + getBinding().v.getHeight() + \"\\n\"\n                + \"View.Width:\" + getBinding().v.getWidth() + \"\\n\";\n        if (event != null) {\n            coordinate += \"MotionEvent.RawX:\" + event.getRawX() + \"\\n\"\n                    + \"MotionEvent.RawY:\" + event.getRawY() + \"\\n\"\n                    + \"MotionEvent.X:\" + event.getX() + \"\\n\"\n                    + \"MotionEvent.Y:\" + event.getY() + \"\\n\";\n        }\n        getBinding().tvCoordinate.setText(coordinate);\n    }\n\n    private void layoutMove(MotionEvent event) {\n        int x = (int) event.getX(), y = (int) event.getY();\n        switch (event.getAction()) {\n            case MotionEvent.ACTION_DOWN:\n                lastX = x;\n                lastY = y;\n                break;\n            case MotionEvent.ACTION_MOVE:\n                int offsetX = x - lastX, offsetY = y - lastY;\n                getBinding().v.layout(getBinding().v.getLeft() + offsetX,\n                        getBinding().v.getTop() + offsetY,\n                        getBinding().v.getRight() + offsetX,\n                        getBinding().v.getBottom() + offsetY);\n                break;\n            case MotionEvent.ACTION_UP:\n                break;\n        }\n    }\n\n    private void offsetMove(MotionEvent event) {\n        int x = (int) event.getX(), y = (int) event.getY();\n        switch (event.getAction()) {\n            case MotionEvent.ACTION_DOWN:\n                lastX = x;\n                lastY = y;\n                break;\n            case MotionEvent.ACTION_MOVE:\n                int offsetX = x - lastX, offsetY = y - lastY;\n                getBinding().v.offsetLeftAndRight(offsetX);\n                getBinding().v.offsetTopAndBottom(offsetY);\n                break;\n            case MotionEvent.ACTION_UP:\n                break;\n        }\n    }\n\n    private void lpMove(MotionEvent event) {\n        int x = (int) event.getX(), y = (int) event.getY();\n        switch (event.getAction()) {\n            case MotionEvent.ACTION_DOWN:\n                lastX = x;\n                lastY = y;\n                break;\n            case MotionEvent.ACTION_MOVE:\n                int offsetX = x - lastX, offsetY = y - lastY;\n                FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getBinding().v.getLayoutParams();\n                lp.leftMargin = getBinding().v.getLeft() + offsetX;\n                lp.topMargin = getBinding().v.getTop() + offsetY;\n                getBinding().v.setLayoutParams(lp);\n                break;\n            case MotionEvent.ACTION_UP:\n                break;\n        }\n    }\n\n    private void scrollByMove(MotionEvent event) {\n        int x = (int) event.getX(), y = (int) event.getY();\n        switch (event.getAction()) {\n            case MotionEvent.ACTION_DOWN:\n                lastX = x;\n                lastY = y;\n                break;\n            case MotionEvent.ACTION_MOVE:\n                int offsetX = x - lastX, offsetY = y - lastY;\n                ((View) getBinding().v.getParent()).scrollBy(-offsetX, -offsetY);\n                break;\n            case MotionEvent.ACTION_UP:\n                break;\n        }\n    }\n\n    private void scrollToMove(MotionEvent event) {\n        int x = (int) event.getX(), y = (int) event.getY();\n        switch (event.getAction()) {\n            case MotionEvent.ACTION_DOWN:\n                lastX = x;\n                lastY = y;\n                break;\n            case MotionEvent.ACTION_MOVE:\n                int offsetX = x - lastX, offsetY = y - lastY;\n                View parent = ((View) getBinding().v.getParent());\n                parent.scrollTo(parent.getScrollX()-offsetX, parent.getScrollY()-offsetY);\n                break;\n            case MotionEvent.ACTION_UP:\n                break;\n        }\n    }\n\n    private void scrollerMove() {\n        getBinding().v.smoothScrollTo(-400, -100);\n    }\n\n    @Override\n    protected void onDestroy() {\n        super.onDestroy();\n        velocityTracker.clear();\n        velocityTracker.recycle();\n    }\n\n    @Override\n    public boolean dispatchTouchEvent(MotionEvent ev) {\n        return super.dispatchTouchEvent(ev);\n    }\n}\n"
  },
  {
    "path": "layout/src/main/res/anim/cycle_7.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<cycleInterpolator xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:cycles=\"4.0\" />\n"
  },
  {
    "path": "layout/src/main/res/anim/layout_anim.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layoutAnimation\n    android:delay=\"500\"\n    android:animation=\"@anim/shake\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\" />"
  },
  {
    "path": "layout/src/main/res/anim/shake.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<translate xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:duration=\"700\"\n    android:fromXDelta=\"0.0\"\n    android:interpolator=\"@anim/cycle_7\"\n    android:toXDelta=\"15.0\" />\n"
  },
  {
    "path": "layout/src/main/res/drawable/branded_background.xml",
    "content": "<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item>\n        <color android:color=\"@color/colorPrimaryDark\"/>\n    </item>\n    <item>\n        <bitmap\n            android:src=\"@drawable/mark_note\"\n            android:tileMode=\"disabled\"\n            android:gravity=\"center\"/>\n    </item>\n</layer-list>\n"
  },
  {
    "path": "layout/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillColor=\"#26A69A\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n"
  },
  {
    "path": "layout/src/main/res/drawable/record_anim.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<animation-list android:oneshot=\"false\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item android:drawable=\"@drawable/record0\" android:duration=\"500\"/>\n    <item android:drawable=\"@drawable/record1\" android:duration=\"500\"/>\n    <item android:drawable=\"@drawable/record2\" android:duration=\"450\"/>\n    <item android:drawable=\"@drawable/record3\" android:duration=\"400\"/>\n    <item android:drawable=\"@drawable/record4\" android:duration=\"350\"/>\n    <item android:drawable=\"@drawable/record5\" android:duration=\"400\"/>\n    <item android:drawable=\"@drawable/record6\" android:duration=\"400\"/>\n</animation-list>"
  },
  {
    "path": "layout/src/main/res/drawable/side_nav_bar.xml",
    "content": "<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"rectangle\">\n    <gradient\n        android:angle=\"135\"\n        android:centerColor=\"#009688\"\n        android:endColor=\"#00695C\"\n        android:startColor=\"#4DB6AC\"\n        android:type=\"linear\" />\n</shape>"
  },
  {
    "path": "layout/src/main/res/drawable-v21/ic_menu_camera.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportHeight=\"24.0\"\n    android:viewportWidth=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M12,12m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0\" />\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M9,2L7.17,4H4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V6c0,-1.1 -0.9,-2 -2,-2h-3.17L15,2H9zm3,15c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5z\" />\n</vector>\n"
  },
  {
    "path": "layout/src/main/res/drawable-v21/ic_menu_gallery.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportHeight=\"24.0\"\n    android:viewportWidth=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M22,16V4c0,-1.1 -0.9,-2 -2,-2H8c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2zm-11,-4l2.03,2.71L16,11l4,5H8l3,-4zM2,6v14c0,1.1 0.9,2 2,2h14v-2H4V6H2z\" />\n</vector>\n"
  },
  {
    "path": "layout/src/main/res/drawable-v21/ic_menu_manage.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportHeight=\"24.0\"\n    android:viewportWidth=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M22.7,19l-9.1,-9.1c0.9,-2.3 0.4,-5 -1.5,-6.9 -2,-2 -5,-2.4 -7.4,-1.3L9,6 6,9 1.6,4.7C0.4,7.1 0.9,10.1 2.9,12.1c1.9,1.9 4.6,2.4 6.9,1.5l9.1,9.1c0.4,0.4 1,0.4 1.4,0l2.3,-2.3c0.5,-0.4 0.5,-1.1 0.1,-1.4z\" />\n</vector>"
  },
  {
    "path": "layout/src/main/res/drawable-v21/ic_menu_send.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportHeight=\"24.0\"\n    android:viewportWidth=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M2.01,21L23,12 2.01,3 2,10l15,2 -15,2z\" />\n</vector>\n"
  },
  {
    "path": "layout/src/main/res/drawable-v21/ic_menu_share.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportHeight=\"24.0\"\n    android:viewportWidth=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,-2.92 -2.92,-2.92z\" />\n</vector>\n"
  },
  {
    "path": "layout/src/main/res/drawable-v21/ic_menu_slideshow.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportHeight=\"24.0\"\n    android:viewportWidth=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M4,6H2v14c0,1.1 0.9,2 2,2h14v-2H4V6zm16,-4H8c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V4c0,-1.1 -0.9,-2 -2,-2zm-8,12.5v-9l6,4.5 -6,4.5z\" />\n</vector>\n"
  },
  {
    "path": "layout/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillType=\"evenOdd\"\n        android:pathData=\"M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"78.5885\"\n                android:endY=\"90.9159\"\n                android:startX=\"48.7653\"\n                android:startY=\"61.0927\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        android:pathData=\"M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\" />\n</vector>\n"
  },
  {
    "path": "layout/src/main/res/layout/activity_adapter.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <LinearLayout\n        android:orientation=\"vertical\" android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <LinearLayout\n            android:orientation=\"horizontal\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\">\n\n            <TextView\n                android:text=\"120dp\"\n                android:textSize=\"20sp\"\n                android:textColor=\"@android:color/white\"\n                android:gravity=\"center\"\n                android:background=\"@android:color/holo_green_dark\"\n                android:layout_width=\"120dp\"\n                android:layout_height=\"80dp\" />\n\n            <TextView\n                android:text=\"240dp\"\n                android:textSize=\"20sp\"\n                android:textColor=\"@android:color/white\"\n                android:gravity=\"center\"\n                android:background=\"@android:color/holo_red_dark\"\n                android:layout_width=\"240dp\"\n                android:layout_height=\"80dp\" />\n\n        </LinearLayout>\n\n    </LinearLayout>\n\n</layout>"
  },
  {
    "path": "layout/src/main/res/layout/activity_bottom_app_bar.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <androidx.coordinatorlayout.widget.CoordinatorLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/rv\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"/>\n\n        <com.google.android.material.bottomappbar.BottomAppBar\n            android:id=\"@+id/bottom_app_bar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"50dp\"\n            android:layout_gravity=\"bottom\"\n            app:backgroundTint=\"@color/colorAccent\"\n            app:fabAlignmentMode=\"center\"\n            app:elevation=\"0dp\"\n            app:layout_behavior=\"@string/hide_bottom_view_on_scroll_behavior\"/>\n\n        <com.google.android.material.floatingactionbutton.FloatingActionButton\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:src=\"@drawable/ic_add_black_24dp\"\n            app:layout_anchor=\"@id/bottom_app_bar\"\n            app:layout_anchorGravity=\"center\"\n            app:fabSize=\"normal\"/>\n\n    </androidx.coordinatorlayout.widget.CoordinatorLayout>\n\n</layout>"
  },
  {
    "path": "layout/src/main/res/layout/activity_bottom_sheet.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    tools:context=\".view.layout.bottomsheet.BottomSheetActivity\">\n\n    <androidx.coordinatorlayout.widget.CoordinatorLayout\n        android:fitsSystemWindows=\"true\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <com.google.android.material.appbar.AppBarLayout\n            android:id=\"@+id/bar_layout\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:theme=\"@style/AppTheme.AppBarOverlay\">\n\n            <androidx.appcompat.widget.Toolbar\n                android:id=\"@+id/toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?attr/actionBarSize\"\n                android:background=\"?attr/colorPrimary\"\n                app:layout_scrollFlags=\"scroll|enterAlways\"\n                app:popupTheme=\"@style/AppTheme.PopupOverlay\">\n\n            </androidx.appcompat.widget.Toolbar>\n\n        </com.google.android.material.appbar.AppBarLayout>\n\n        <RelativeLayout\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\">\n\n            <TextView\n                android:text=\"@string/bottom_sheet_default_content\"\n                android:textSize=\"18sp\"\n                android:gravity=\"center\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\" />\n\n        </RelativeLayout>\n\n        <RelativeLayout\n            android:id=\"@+id/bottom_sheet\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentBottom=\"true\"\n            app:behavior_hideable=\"true\"\n            app:behavior_peekHeight=\"200dp\"\n            app:layout_behavior=\"@string/bottom_sheet_behavior\">\n\n            <RelativeLayout\n                android:background=\"@android:color/holo_green_light\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\">\n\n            </RelativeLayout>\n\n        </RelativeLayout>\n\n        <com.google.android.material.floatingactionbutton.FloatingActionButton\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_margin=\"@dimen/fab_margin\"\n            android:src=\"@drawable/ic_account_circle_black_24dp\"\n            android:tint=\"@android:color/white\"\n            app:borderWidth=\"0dp\"\n            app:layout_anchor=\"@id/bottom_sheet\"\n            app:layout_anchorGravity=\"right|top\" />\n\n    </androidx.coordinatorlayout.widget.CoordinatorLayout>\n\n</layout>"
  },
  {
    "path": "layout/src/main/res/layout/activity_collapse_bar_structure.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <androidx.coordinatorlayout.widget.CoordinatorLayout\n        android:fitsSystemWindows=\"true\"\n        android:id=\"@+id/main_content\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <com.google.android.material.appbar.AppBarLayout\n            android:id=\"@+id/appbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"230dp\"\n            android:theme=\"@style/ThemeOverlay.AppCompat.Dark.ActionBar\">\n\n            <com.google.android.material.appbar.CollapsingToolbarLayout\n                android:id=\"@+id/collapsing_toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                app:contentScrim=\"?attr/colorPrimary\"\n                app:layout_scrollFlags=\"scroll|exitUntilCollapsed\">\n\n                <LinearLayout\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"230dp\"\n                    android:background=\"@color/colorAccent\"\n                    android:gravity=\"center\"\n                    android:orientation=\"vertical\">\n\n                    <androidx.appcompat.widget.AppCompatImageView\n                        android:layout_width=\"96dp\"\n                        android:layout_height=\"96dp\"\n                        android:scaleType=\"centerCrop\"\n                        android:layout_marginTop=\"24dp\"\n                        android:src=\"@mipmap/ic_launcher\"/>\n\n                    <TextView\n                        android:layout_width=\"wrap_content\"\n                        android:layout_height=\"wrap_content\"\n                        android:gravity=\"center\"\n                        android:text=\"@string/app_name\"\n                        android:layout_marginTop=\"8dp\"\n                        android:textColor=\"@android:color/black\"\n                        android:textSize=\"18sp\"/>\n\n                    <TextView\n                        android:id=\"@+id/tv_version\"\n                        android:layout_width=\"wrap_content\"\n                        android:layout_height=\"wrap_content\"\n                        android:layout_marginTop=\"8dp\"\n                        android:textColor=\"@android:color/black\"\n                        android:textSize=\"14sp\"\n                        android:text=\"Version 1.2.3\"/>\n\n                </LinearLayout>\n\n                <androidx.appcompat.widget.Toolbar\n                    android:id=\"@+id/toolbar\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"?attr/actionBarSize\"\n                    android:background=\"@android:color/transparent\"\n                    app:layout_collapseMode=\"pin\"/>\n\n            </com.google.android.material.appbar.CollapsingToolbarLayout>\n\n        </com.google.android.material.appbar.AppBarLayout>\n\n        <androidx.core.widget.NestedScrollView\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\n\n            <TextView\n                android:textSize=\"16sp\"\n                android:text=\"@string/lan_ting_xu\"\n                android:padding=\"16dp\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\" />\n\n        </androidx.core.widget.NestedScrollView>\n\n    </androidx.coordinatorlayout.widget.CoordinatorLayout>\n\n</layout>"
  },
  {
    "path": "layout/src/main/res/layout/activity_drawer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.drawerlayout.widget.DrawerLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:id=\"@+id/drawer_layout\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:fitsSystemWindows=\"true\"\n    tools:openDrawer=\"start\">\n\n    <include\n        layout=\"@layout/app_bar_drawer\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\" />\n\n    <com.google.android.material.navigation.NavigationView\n        android:id=\"@+id/nav_view\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"match_parent\"\n        android:layout_gravity=\"start\"\n        android:fitsSystemWindows=\"true\"\n        app:headerLayout=\"@layout/nav_header_drawer\"\n        app:menu=\"@menu/activity_drawer_drawer\" />\n\n</androidx.drawerlayout.widget.DrawerLayout>\n"
  },
  {
    "path": "layout/src/main/res/layout/activity_edit_layout.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <LinearLayout\n        android:id=\"@+id/container\"\n        android:background=\"#d4d4d4\"\n        android:orientation=\"vertical\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <LinearLayout\n            android:id=\"@+id/ll\"\n            android:layout_gravity=\"center_horizontal\"\n            android:background=\"@android:color/holo_red_light\"\n            android:padding=\"10px\"\n            android:layout_margin=\"10px\"\n            android:layout_width=\"120dp\"\n            android:layout_height=\"100dp\"\n            android:orientation=\"horizontal\" >\n\n            <View\n                android:id=\"@+id/v\"\n                android:background=\"@android:color/holo_green_dark\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"/>\n\n        </LinearLayout>\n\n        <androidx.appcompat.widget.AppCompatTextView\n            android:id=\"@+id/tv_info\"\n            android:padding=\"16dp\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\" />\n\n    </LinearLayout>\n\n</layout>"
  },
  {
    "path": "layout/src/main/res/layout/activity_layout_menu.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    tools:context=\".view.LayoutMenuActivity\">\n\n    <RelativeLayout\n        android:fitsSystemWindows=\"true\"\n        android:background=\"@android:color/background_light\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <include android:id=\"@+id/bar_layout\" layout=\"@layout/layout_toolbar\"/>\n\n        <androidx.core.widget.NestedScrollView\n            android:layout_below=\"@id/bar_layout\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\">\n\n            <LinearLayout\n                android:orientation=\"vertical\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\">\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/bnt_nav\"\n                    android:text=\"@string/menu_item_sub_title_1\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/bnt_tabbed\"\n                    android:text=\"@string/menu_item_sub_title_2\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/bnt_bottom_sheet\"\n                    android:text=\"@string/menu_item_sub_title_3\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/bnt_scrolling\"\n                    android:text=\"@string/menu_item_sub_title_4\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/bnt_collapse\"\n                    android:text=\"@string/menu_item_sub_title_5\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn_drawer\"\n                    android:text=\"Drawer Layout\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/bnt_support_28\"\n                    android:text=\"Support 28 库\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn_view_system\"\n                    android:text=\"View System\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn_view_animate\"\n                    android:text=\"View Animate\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn_swipe\"\n                    android:text=\"Swipe Back\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn_adapter\"\n                    android:text=\"Screen Adapter\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn_edit\"\n                    android:text=\"Edit layout\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n            </LinearLayout>\n\n        </androidx.core.widget.NestedScrollView>\n\n        <View android:layout_below=\"@id/bar_layout\"\n            android:background=\"@drawable/bg_toolbar_shade\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"5dp\"/>\n\n    </RelativeLayout>\n\n</layout>"
  },
  {
    "path": "layout/src/main/res/layout/activity_navigation.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout>\n\n    <LinearLayout\n        xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:fitsSystemWindows=\"true\"\n        android:orientation=\"vertical\">\n\n        <FrameLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\"\n            android:id=\"@+id/fragment_container\" />\n\n        <com.google.android.material.bottomnavigation.BottomNavigationView\n            android:id=\"@+id/nav\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:background=\"@color/colorPrimaryDark\"\n            app:itemIconTint=\"@drawable/nav_item_color\"\n            app:itemTextColor=\"@drawable/nav_item_color\"\n            android:gravity=\"bottom\"\n            android:focusable=\"true\"\n            android:clickable=\"true\"\n            app:elevation=\"8dp\"\n            app:menu=\"@menu/bottom_navigation\" />\n\n    </LinearLayout>\n\n</layout>"
  },
  {
    "path": "layout/src/main/res/layout/activity_scrolling.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <androidx.coordinatorlayout.widget.CoordinatorLayout\n        android:fitsSystemWindows=\"true\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <com.google.android.material.appbar.AppBarLayout\n            android:id=\"@+id/app_bar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"230dp\"\n            android:theme=\"@style/AppTheme.AppBarOverlay\">\n\n            <com.google.android.material.appbar.CollapsingToolbarLayout\n                android:id=\"@+id/toolbar_layout\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                app:contentScrim=\"@color/colorAccent\"\n                app:layout_scrollFlags=\"scroll|exitUntilCollapsed\">\n\n                <androidx.appcompat.widget.Toolbar\n                    android:id=\"@+id/toolbar\"\n                    app:titleTextColor=\"@android:color/black\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"?attr/actionBarSize\"\n                    app:layout_collapseMode=\"pin\"\n                    app:popupTheme=\"@style/AppTheme.PopupOverlay\" />\n\n            </com.google.android.material.appbar.CollapsingToolbarLayout>\n\n        </com.google.android.material.appbar.AppBarLayout>\n\n        <androidx.core.widget.NestedScrollView\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\n\n            <TextView\n                android:textSize=\"16sp\"\n                android:text=\"@string/lan_ting_xu\"\n                android:padding=\"16dp\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\" />\n\n        </androidx.core.widget.NestedScrollView>\n\n        <com.google.android.material.floatingactionbutton.FloatingActionButton\n            android:id=\"@+id/fab\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_margin=\"@dimen/fab_margin\"\n            app:layout_anchor=\"@id/app_bar\"\n            app:layout_anchorGravity=\"bottom|end\"\n            app:srcCompat=\"@android:drawable/ic_dialog_email\" />\n\n    </androidx.coordinatorlayout.widget.CoordinatorLayout>\n\n</layout>"
  },
  {
    "path": "layout/src/main/res/layout/activity_support_28.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <LinearLayout\n        android:orientation=\"vertical\"\n        android:gravity=\"center_horizontal\"\n        android:fitsSystemWindows=\"true\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <com.google.android.material.button.MaterialButton\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:text=\"Material button\"\n            android:textSize=\"18sp\"\n            style=\"@style/Widget.MaterialComponents.Button\"\n            app:icon=\"@drawable/ic_autorenew_black_24dp\"/>\n\n        <com.google.android.material.chip.ChipGroup\n            android:layout_marginTop=\"20dp\"\n            style=\"@style/Widget.MaterialComponents.ChipGroup\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\">\n\n            <com.google.android.material.chip.Chip\n                android:text=\"This is a Chip 1\"\n                style=\"@style/TextAppearance.MaterialComponents.Chip\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\" />\n\n            <com.google.android.material.chip.Chip\n                android:text=\"Chip 2\"\n                app:textEndPadding=\"8dp\"\n                style=\"@style/TextAppearance.MaterialComponents.Chip\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\" />\n\n            <com.google.android.material.chip.Chip\n                android:text=\"Chip 3\"\n                app:rippleColor=\"@android:color/holo_red_dark\"\n                style=\"@style/TextAppearance.MaterialComponents.Chip\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\" />\n\n            <com.google.android.material.chip.Chip\n                android:text=\"Chip 4\"\n                app:closeIconVisible=\"true\"\n                style=\"@style/TextAppearance.MaterialComponents.Chip\"\n                app:checkedIcon=\"@drawable/ic_check_circle_black_24dp\"\n                app:closeIcon=\"@drawable/ic_close_black_24dp\"\n                app:chipIcon=\"@drawable/ic_autorenew_black_24dp\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\" />\n\n            <com.google.android.material.chip.Chip\n                android:text=\"Chip 5\"\n                app:chipIconTint=\"@android:color/holo_red_dark\"\n                style=\"@style/TextAppearance.MaterialComponents.Chip\"\n                app:chipIcon=\"@drawable/ic_autorenew_black_24dp\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\" />\n\n        </com.google.android.material.chip.ChipGroup>\n\n        <com.google.android.material.card.MaterialCardView\n            style=\"@style/Widget.MaterialComponents.CardView\"\n            android:layout_marginTop=\"20dp\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_margin=\"10dp\">\n\n            <androidx.appcompat.widget.AppCompatTextView\n                android:textSize=\"30sp\"\n                android:text=\"This is the android.support.design.card.MaterialCardView\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\" />\n\n        </com.google.android.material.card.MaterialCardView>\n\n        <com.google.android.material.circularreveal.CircularRevealFrameLayout\n            android:id=\"@+id/crfl\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"200dp\">\n\n            <androidx.appcompat.widget.AppCompatImageView\n                android:layout_gravity=\"center\"\n                android:src=\"@android:color/holo_green_dark\"\n                android:layout_width=\"80dp\"\n                android:layout_height=\"80dp\" />\n\n        </com.google.android.material.circularreveal.CircularRevealFrameLayout>\n\n\n        <com.google.android.material.button.MaterialButton\n            android:id=\"@+id/btn_bottom_bar\"\n            android:text=\"Bottom App Bar\"\n            style=\"@style/Widget.MaterialComponents.Button\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\" />\n\n        <com.google.android.material.button.MaterialButton\n            android:id=\"@+id/btn_sheet_dialog\"\n            android:text=\"Bottom App Bar\"\n            style=\"@style/Widget.MaterialComponents.Button\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\" />\n\n    </LinearLayout>\n\n</layout>"
  },
  {
    "path": "layout/src/main/res/layout/activity_swipe_back.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:orientation=\"vertical\"\n    android:background=\"@android:color/holo_purple\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n</LinearLayout>"
  },
  {
    "path": "layout/src/main/res/layout/activity_tabbed.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    tools:context=\".view.layout.tabbed.TabbedActivity\">\n\n    <androidx.coordinatorlayout.widget.CoordinatorLayout\n        android:id=\"@+id/main_content\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:fitsSystemWindows=\"true\">\n\n        <com.google.android.material.appbar.AppBarLayout\n            android:id=\"@+id/bar_layout\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:theme=\"@style/AppTheme.AppBarOverlay\">\n\n            <androidx.appcompat.widget.Toolbar\n                android:id=\"@+id/toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?attr/actionBarSize\"\n                android:background=\"?attr/colorPrimary\"\n                app:layout_scrollFlags=\"scroll|enterAlways\"\n                app:popupTheme=\"@style/AppTheme.PopupOverlay\">\n\n            </androidx.appcompat.widget.Toolbar>\n\n        </com.google.android.material.appbar.AppBarLayout>\n\n        <androidx.viewpager.widget.ViewPager\n            android:id=\"@+id/vp\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\" />\n\n        <com.google.android.material.floatingactionbutton.FloatingActionButton\n            android:id=\"@+id/fab\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"end|bottom\"\n            android:layout_margin=\"@dimen/fab_margin\"\n            app:srcCompat=\"@android:drawable/ic_dialog_email\"\n            app:backgroundTint=\"@color/colorAccent\"/>\n\n    </androidx.coordinatorlayout.widget.CoordinatorLayout>\n\n</layout>"
  },
  {
    "path": "layout/src/main/res/layout/activity_view_animate.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <androidx.core.widget.NestedScrollView\n        android:fitsSystemWindows=\"true\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <LinearLayout\n            android:orientation=\"vertical\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\">\n\n            <FrameLayout\n                android:background=\"@android:color/holo_green_light\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"200dp\">\n\n                <View\n                    android:id=\"@+id/v\"\n                    android:layout_gravity=\"center\"\n                    android:background=\"@android:color/holo_red_light\"\n                    android:layout_width=\"100dp\"\n                    android:layout_height=\"100dp\"/>\n\n            </FrameLayout>\n\n            <androidx.appcompat.widget.AppCompatButton\n                android:id=\"@+id/btn_aniamte\"\n                android:text=\"Animate\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\" />\n\n            <androidx.appcompat.widget.AppCompatButton\n                android:id=\"@+id/btn_shake\"\n                android:text=\"Shake\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\" />\n\n            <ImageView\n                android:id=\"@+id/iv_record\"\n                android:layout_gravity=\"center_horizontal\"\n                android:layout_width=\"100dp\"\n                android:layout_height=\"100dp\" />\n\n        </LinearLayout>\n\n    </androidx.core.widget.NestedScrollView>\n\n</layout>"
  },
  {
    "path": "layout/src/main/res/layout/activity_view_system.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\" >\n\n    <LinearLayout\n        android:fitsSystemWindows=\"true\"\n        android:orientation=\"vertical\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <FrameLayout\n            android:background=\"@android:color/holo_green_light\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"200dp\">\n\n            <me.shouheng.layout.view.views.CustomView\n                android:id=\"@+id/v\"\n                android:background=\"@android:color/holo_red_light\"\n                android:layout_gravity=\"center\"\n                android:layout_width=\"200dp\"\n                android:layout_height=\"100dp\"/>\n\n        </FrameLayout>\n\n        <TextView\n            android:id=\"@+id/tv_coordinate\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_trans\"\n            android:text=\"Transition\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_scroller\"\n            android:text=\"Scroller Move\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\" />\n\n        <FrameLayout\n            android:background=\"@android:color/holo_green_light\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"150dp\">\n\n            <me.shouheng.layout.view.views.CustomView\n                android:id=\"@+id/vg\"\n                android:background=\"@android:color/holo_red_light\"\n                android:layout_gravity=\"center\"\n                android:layout_width=\"200dp\"\n                android:layout_height=\"100dp\"/>\n\n        </FrameLayout>\n\n        <androidx.appcompat.widget.AppCompatTextView\n            android:id=\"@+id/tv_velocity\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_velocity\"\n            android:text=\"Show velocity\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\" />\n\n    </LinearLayout>\n\n</layout>"
  },
  {
    "path": "layout/src/main/res/layout/app_bar_drawer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\".view.DrawerActivity\">\n\n    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\">\n\n        <androidx.appcompat.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?attr/actionBarSize\"\n            android:background=\"?attr/colorPrimary\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\" />\n\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <include layout=\"@layout/content_drawer\" />\n\n    <com.google.android.material.floatingactionbutton.FloatingActionButton\n        android:id=\"@+id/fab\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"bottom|end\"\n        android:layout_margin=\"@dimen/fab_margin\"\n        app:srcCompat=\"@android:drawable/ic_dialog_email\" />\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "layout/src/main/res/layout/bottom_sheet_dialog.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:background=\"@android:color/holo_green_dark\"\n    android:orientation=\"vertical\" android:layout_width=\"match_parent\"\n    android:layout_height=\"300dp\">\n\n</LinearLayout>"
  },
  {
    "path": "layout/src/main/res/layout/content_drawer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n    tools:context=\".view.DrawerActivity\"\n    tools:showIn=\"@layout/app_bar_drawer\">\n\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "layout/src/main/res/layout/fragment_normal_tips.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\">\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <include android:id=\"@+id/bar_layout\" layout=\"@layout/layout_toolbar\"/>\n\n        <RelativeLayout\n            android:layout_below=\"@id/bar_layout\"\n            android:gravity=\"center\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\">\n\n            <TextView\n                android:id=\"@+id/tv_title\"\n                tools:text=\"This is the demo title\"\n                android:textSize=\"18sp\"\n                android:padding=\"16dp\"\n                android:gravity=\"center\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\" />\n\n            <TextView\n                android:id=\"@+id/tv_content\"\n                android:layout_below=\"@id/tv_title\"\n                tools:text=\"This is the demo content for the fucking normal tips content text view\"\n                android:textSize=\"16sp\"\n                android:padding=\"8dp\"\n                android:gravity=\"center\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\" />\n\n        </RelativeLayout>\n\n        <View android:id=\"@+id/shader\"\n            android:layout_below=\"@id/bar_layout\"\n            android:background=\"@drawable/bg_toolbar_shade\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"5dp\"/>\n\n    </RelativeLayout>\n\n</layout>"
  },
  {
    "path": "layout/src/main/res/layout/fragment_pager.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\">\n\n    <androidx.coordinatorlayout.widget.CoordinatorLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <com.google.android.material.appbar.AppBarLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:theme=\"@style/AppTheme.AppBarOverlay\"\n            android:id=\"@+id/bar_layout\">\n\n            <androidx.appcompat.widget.Toolbar\n                android:id=\"@+id/toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?attr/actionBarSize\"\n                app:popupTheme=\"@style/AppTheme.PopupOverlay\"\n                app:layout_scrollFlags=\"scroll|enterAlways\" />\n\n            <com.google.android.material.tabs.TabLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:id=\"@+id/tab_layout\"\n                app:tabBackground=\"@color/colorPrimary\"\n                app:tabIndicatorColor=\"@color/colorAccent\"\n                app:tabSelectedTextColor=\"@color/colorAccent\"\n                app:tabTextColor=\"@drawable/nav_item_color\"\n                app:tabGravity=\"fill\" />\n\n        </com.google.android.material.appbar.AppBarLayout>\n\n        <androidx.viewpager.widget.ViewPager\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:id=\"@+id/vp\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\" />\n\n        <com.google.android.material.floatingactionbutton.FloatingActionButton\n            android:id=\"@+id/fab\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"bottom|end\"\n            android:layout_margin=\"@dimen/fab_margin\"\n            android:src=\"@drawable/ic_close_black_24dp\"\n            android:tint=\"@android:color/white\"\n            app:backgroundTint=\"@color/colorAccent\"/>\n\n    </androidx.coordinatorlayout.widget.CoordinatorLayout>\n\n</layout>"
  },
  {
    "path": "layout/src/main/res/layout/nav_header_drawer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"@dimen/nav_header_height\"\n    android:background=\"@drawable/side_nav_bar\"\n    android:gravity=\"bottom\"\n    android:orientation=\"vertical\"\n    android:paddingBottom=\"@dimen/activity_vertical_margin\"\n    android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n    android:paddingRight=\"@dimen/activity_horizontal_margin\"\n    android:paddingTop=\"@dimen/activity_vertical_margin\"\n    android:theme=\"@style/ThemeOverlay.AppCompat.Dark\">\n\n    <TextView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:paddingTop=\"@dimen/nav_header_vertical_spacing\"\n        android:text=\"@string/nav_header_title\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Body1\" />\n\n    <TextView\n        android:id=\"@+id/textView\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"@string/nav_header_subtitle\" />\n\n</LinearLayout>\n"
  },
  {
    "path": "layout/src/main/res/menu/activity_drawer_drawer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    tools:showIn=\"navigation_view\">\n\n    <group android:checkableBehavior=\"single\">\n        <item\n            android:id=\"@+id/nav_camera\"\n            android:icon=\"@drawable/ic_menu_camera\"\n            android:title=\"Import\" />\n        <item\n            android:id=\"@+id/nav_gallery\"\n            android:icon=\"@drawable/ic_menu_gallery\"\n            android:title=\"Gallery\" />\n        <item\n            android:id=\"@+id/nav_slideshow\"\n            android:icon=\"@drawable/ic_menu_slideshow\"\n            android:title=\"Slideshow\" />\n        <item\n            android:id=\"@+id/nav_manage\"\n            android:icon=\"@drawable/ic_menu_manage\"\n            android:title=\"Tools\" />\n    </group>\n\n    <item android:title=\"Communicate\">\n        <menu>\n            <item\n                android:id=\"@+id/nav_share\"\n                android:icon=\"@drawable/ic_menu_share\"\n                android:title=\"Share\" />\n            <item\n                android:id=\"@+id/nav_send\"\n                android:icon=\"@drawable/ic_menu_send\"\n                android:title=\"Send\" />\n        </menu>\n    </item>\n\n</menu>\n"
  },
  {
    "path": "layout/src/main/res/menu/bottom_navigation.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <item android:enabled=\"true\"\n        app:showAsAction=\"always\"\n        android:icon=\"@drawable/ic_widgets_black_24dp\"\n        android:title=\"@string/nav_bottom_item_1\" />\n\n    <item android:enabled=\"true\"\n        app:showAsAction=\"always\"\n        android:icon=\"@drawable/ic_favorite_black_24dp\"\n        android:title=\"@string/nav_bottom_item_3\" />\n\n    <group\n        android:checkableBehavior=\"single\"\n        android:enabled=\"true\">\n\n        <item\n            android:id=\"@+id/nav_main\"\n            android:enabled=\"true\"\n            android:icon=\"@drawable/ic_widgets_black_24dp\"\n            android:title=\"@string/nav_bottom_item_1\" />\n\n        <item\n            android:id=\"@+id/nav_favorite\"\n            android:enabled=\"true\"\n            android:icon=\"@drawable/ic_favorite_black_24dp\"\n            android:title=\"@string/nav_bottom_item_3\" />\n\n        <item\n            android:id=\"@+id/nav_info\"\n            android:enabled=\"true\"\n            android:icon=\"@drawable/ic_account_circle_black_24dp\"\n            android:title=\"@string/nav_bottom_item_3\" />\n\n    </group>\n</menu>"
  },
  {
    "path": "layout/src/main/res/menu/drawer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n    <item\n        android:id=\"@+id/action_settings\"\n        android:orderInCategory=\"100\"\n        android:title=\"@string/action_settings\"\n        app:showAsAction=\"never\" />\n</menu>\n"
  },
  {
    "path": "layout/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "layout/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "layout/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#FAFAFA</color>\n    <color name=\"colorPrimaryDark\">#FAFAFA</color>\n    <color name=\"colorAccent\">#0078FF</color>\n</resources>\n"
  },
  {
    "path": "layout/src/main/res/values/dimens.xml",
    "content": "<resources>\n    <!-- Default screen margins, per the Android Design guidelines. -->\n    <dimen name=\"activity_horizontal_margin\">16dp</dimen>\n    <dimen name=\"activity_vertical_margin\">16dp</dimen>\n    <dimen name=\"nav_header_vertical_spacing\">8dp</dimen>\n    <dimen name=\"nav_header_height\">176dp</dimen>\n    <dimen name=\"fab_margin\">16dp</dimen>\n</resources>"
  },
  {
    "path": "layout/src/main/res/values/drawables.xml",
    "content": "<resources xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item name=\"ic_menu_camera\" type=\"drawable\">@android:drawable/ic_menu_camera</item>\n    <item name=\"ic_menu_gallery\" type=\"drawable\">@android:drawable/ic_menu_gallery</item>\n    <item name=\"ic_menu_slideshow\" type=\"drawable\">@android:drawable/ic_menu_slideshow</item>\n    <item name=\"ic_menu_manage\" type=\"drawable\">@android:drawable/ic_menu_manage</item>\n    <item name=\"ic_menu_share\" type=\"drawable\">@android:drawable/ic_menu_share</item>\n    <item name=\"ic_menu_send\" type=\"drawable\">@android:drawable/ic_menu_send</item>\n</resources>\n"
  },
  {
    "path": "layout/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">layout</string>\n    <string name=\"title_activity_drawer\">DrawerActivity</string>\n    <string name=\"navigation_drawer_open\">Open navigation drawer</string>\n    <string name=\"navigation_drawer_close\">Close navigation drawer</string>\n    <string name=\"nav_header_title\">Android Studio</string>\n    <string name=\"nav_header_subtitle\">android.studio@android.com</string>\n    <string name=\"nav_header_desc\">Navigation header</string>\n    <string name=\"action_settings\">Settings</string>\n</resources>\n"
  },
  {
    "path": "layout/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <style name=\"AppTheme\" parent=\"Theme.MaterialComponents.Light.NoActionBar.Bridge\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/light_theme_background</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n\n        <item name=\"colorPrimaryVariant\">@android:color/holo_red_light</item>\n        <item name=\"colorSecondaryVariant\">@android:color/holo_orange_light</item>\n        <item name=\"colorSurface\">@android:color/holo_blue_light</item>\n        <item name=\"colorOnPrimary\">@android:color/holo_blue_light</item>\n        <item name=\"colorOnSecondary\">@android:color/holo_purple</item>\n    </style>\n\n    <style name=\"AppTheme.Branded\" parent=\"AppTheme\">\n        <item name=\"android:windowBackground\">@drawable/branded_background</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "layout/src/main/res/values-v21/styles.xml",
    "content": "<resources></resources>\n"
  },
  {
    "path": "layout/src/test/java/me/shouheng/layout/ExampleUnitTest.java",
    "content": "package me.shouheng.layout;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n\n    @Test\n    public void dpTestCase1() {\n        int width = 720, height = 1280;\n        float inch = 4.7f;\n        float result = (float) (Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)) / inch);\n        assertEquals(360, result, 0.1);\n    }\n\n    @Test\n    public void dpTestCase2() {\n        int width = 1920, height = 1080;\n        float inch = 5f;\n        float result = (float) (Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)) / inch);\n        assertEquals(440, result, 0.1);\n    }\n}"
  },
  {
    "path": "libraries/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "libraries/build.gradle",
    "content": "println isLibraryModuleApp.toBoolean()\n\nif (isLibraryModuleApp.toBoolean()) {\n    apply plugin: 'com.android.application'\n} else {\n    apply plugin: 'com.android.library'\n}\n\nandroid {\n    compileSdkVersion rootProject.ext.compileSdkVersion\n    defaultConfig {\n        minSdkVersion rootProject.ext.minSdkVersion\n        targetSdkVersion rootProject.ext.targetSdkVersion\n        versionCode 1\n        versionName \"1.0\"\n        multiDexEnabled true\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n        javaCompileOptions {\n            annotationProcessorOptions {\n                arguments = [moduleName: project.getName()]\n            }\n        }\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n    // use data binding\n    dataBinding {\n        enabled = true\n    }\n    // use java 8 language\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n    // use external libs folder\n    sourceSets {\n        main {\n            jniLibs.srcDirs = ['libs']\n            if (isLibraryModuleApp.toBoolean()) {\n                manifest.srcFile \"src/main/debug/AndroidManifest.xml\"\n            } else {\n                manifest.srcFile \"src/main/AndroidManifest.xml\"\n            }\n        }\n    }\n}\n\ndependencies {\n    implementation fileTree(dir: 'libs', include: ['*.jar'])\n    // router\n    annotationProcessor 'com.alibaba:arouter-compiler:1.1.4'\n    // knife\n    implementation project(':knife-api')\n    implementation project(':knife-annotation')\n    annotationProcessor project(':knife-compiler')\n    // event bus\n    implementation 'org.greenrobot:eventbus:3.1.1'\n    // fingerprint\n//    implementation 'com.wei.android.lib:fingerprintidentify:1.2.1'\n    // work manager\n    implementation \"android.arch.work:work-runtime:1.0.0-alpha10\"\n    // projects\n    implementation project(':commons')\n}\n"
  },
  {
    "path": "libraries/proguard-rules.pro",
    "content": "# EventBus\n-keepattributes *Annotation*\n-keepclassmembers class * {\n    @org.greenrobot.eventbus.Subscribe <methods>;\n}\n-keep enum org.greenrobot.eventbus.ThreadMode { *; }\n# Only required if you use AsyncExecutor\n-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {\n    <init>(java.lang.Throwable);\n}\n\n\n"
  },
  {
    "path": "libraries/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"me.shouheng.libraries\">\n\n    <uses-permission android:name=\"android.permission.USE_FINGERPRINT\"/>\n    <uses-permission android:name=\"com.fingerprints.service.ACCESS_FINGERPRINT_MANAGER\"/>\n    <uses-permission android:name=\"com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY\"/>\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <activity android:name=\".MenuActivity\" />\n        <activity android:name=\".eventbus.EventBusActivity1\" />\n        <activity android:name=\".eventbus.EventBusActivity2\" />\n        <activity android:name=\".rxjava.RxJavaActivity\" />\n        <activity android:name=\".rxjava.RxBusActivity\" />\n        <activity android:name=\".image.ClipPictureActivity\" />\n        <activity android:name=\".TimberActivity\" />\n        <activity android:name=\".MyKnifeActivity\"/>\n        <activity android:name=\".FingerprintIdentifyActivity\"/>\n        <activity android:name=\".workmanager.WorkManagerActivity\"/>\n        <activity android:name=\".serial.SerializeActivity\"/>\n        <activity android:name=\".handler.HandlerActivity\"/>\n        <service android:name=\".handler.FileRecognizeTask\"/>\n    </application>\n\n</manifest>"
  },
  {
    "path": "libraries/src/main/debug/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"me.shouheng.libraries\">\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:name=\".ModuleLibraryApp\"\n        android:theme=\"@style/AppTheme\" >\n        <activity android:name=\".MenuActivity\" >\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <action android:name=\"android.intent.action.VIEW\"/>\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n        <activity android:name=\".eventbus.EventBusActivity1\"/>\n        <activity android:name=\".eventbus.EventBusActivity2\"/>\n        <activity android:name=\".rxjava.RxJavaActivity\"/>\n        <activity android:name=\".rxjava.RxBusActivity\"/>\n        <activity android:name=\".image.ClipPictureActivity\"/>\n        <activity android:name=\".MyKnifeActivity\"/>\n        <activity android:name=\".FingerprintIdentifyActivity\"/>\n        <activity android:name=\".workmanager.WorkManagerActivity\"/>\n        <activity android:name=\".serial.SerializeActivity\"/>\n        <activity android:name=\".handler.HandlerActivity\"/>\n        <service android:name=\".handler.FileRecognizeTask\"/>\n        <activity android:name=\".image.ImageCompressActivity\"/>\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "libraries/src/main/java/me/shouheng/libraries/FingerprintIdentifyActivity.java",
    "content": "package me.shouheng.libraries;\n\nimport android.os.Bundle;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n//import com.wei.android.lib.fingerprintidentify.FingerprintIdentify;\n//import com.wei.android.lib.fingerprintidentify.base.BaseFingerprint;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.libraries.databinding.ActivityFingerprintIdentifyBinding;\n\n/**\n * TODO need to handle this problem by downloading the library and automatically migrate to AndroidX\n *\n * @author shouh\n * @version $Id: FingerprintIdentifyActivity, v 0.1 2018/8/25 14:45 shouh Exp$\n */\n@Route(path = BaseConstants.LIBRARY_FINGERPRIINT_IDENTIFY)\npublic class FingerprintIdentifyActivity extends CommonActivity<ActivityFingerprintIdentifyBinding> {\n\n//    private FingerprintIdentify mFingerprintIdentify;\n\n    private static final int MAX_AVAILABLE_TIMES = 5;\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_fingerprint_identify;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n//        long time = System.currentTimeMillis();\n//        mFingerprintIdentify = new FingerprintIdentify(getApplicationContext(), exception ->\n//                append(\"\\nException：\" + exception.getLocalizedMessage()));\n//        append(\"\\ninitialize cost \" + (System.currentTimeMillis() - time) + \" ms\");\n//        append(\"\\nisHardwareEnable() \" + mFingerprintIdentify.isHardwareEnable());\n//        append(\"\\nisRegisteredFingerprint() \" + mFingerprintIdentify.isRegisteredFingerprint());\n//        append(\"\\nisFingerprintEnable() \" + mFingerprintIdentify.isFingerprintEnable());\n//\n//        if (!mFingerprintIdentify.isFingerprintEnable()) {\n//            append(\"\\nfingerprint not support\");\n//            return;\n//        }\n//        append(\"\\nCLICK IDENTIFY BUTTON TO START!\");\n//\n//        getBinding().btnIdentify.setOnClickListener(v -> startIdentify());\n    }\n\n//    private void startIdentify() {\n//        append(\"\\nIDENTIFY START!\");\n//        mFingerprintIdentify.startIdentify(MAX_AVAILABLE_TIMES, new BaseFingerprint.FingerprintIdentifyListener() {\n//            @Override\n//            public void onSucceed() {\n//                append(\"\\nonSucceed\");\n//            }\n//\n//            @Override\n//            public void onNotMatch(int availableTimes) {\n//                append(\"\\nonNotMatch : availableTimes = \" + availableTimes);\n//            }\n//\n//            @Override\n//            public void onFailed(boolean isDeviceLocked) {\n//                append(\"\\nonFailed : isDeviceLocked = \" + isDeviceLocked);\n//            }\n//\n//            @Override\n//            public void onStartFailedByDeviceLocked() {\n//                append(\"\\nonStartFailedByDeviceLocked\");\n//            }\n//        });\n//    }\n\n//    private void append(String msg) {\n//        getBinding().tvResult.append(msg);\n//    }\n}\n"
  },
  {
    "path": "libraries/src/main/java/me/shouheng/libraries/MenuActivity.java",
    "content": "package me.shouheng.libraries;\n\nimport android.os.Bundle;\nimport androidx.appcompat.app.ActionBar;\nimport androidx.appcompat.widget.Toolbar;\nimport android.view.MenuItem;\nimport android.view.View;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.alibaba.android.arouter.launcher.ARouter;\n\nimport java.util.Calendar;\nimport java.util.Date;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.ToastUtils;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.libraries.databinding.ActivityMenuBinding;\nimport me.shouheng.libraries.serial.SerializeActivity;\n\n@Route(path = BaseConstants.LIBRARY_MENU)\npublic class MenuActivity extends CommonActivity<ActivityMenuBinding> {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_menu;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        configToolbar();\n\n        getBinding().bntEventBus.setOnClickListener(v ->\n                ARouter.getInstance()\n                        .build(BaseConstants.LIBRARY_EVENT_BUS_ACTIVITY1)\n                        .navigation());\n        getBinding().btnRxjava.setOnClickListener(v ->\n                ARouter.getInstance()\n                        .build(BaseConstants.LIBRARY_RX_JAVA)\n                        .navigation());\n        getBinding().btnClip.setOnClickListener(v ->\n                ARouter.getInstance()\n                        .build(BaseConstants.LIBRARY_CLIP_PIC)\n                        .navigation());\n        getBinding().btnTimber.setOnClickListener(v ->\n                ARouter.getInstance()\n                        .build(BaseConstants.LIBRARY_TIMBER)\n                        .navigation());\n        getBinding().btnMyKnife.setOnClickListener(v ->\n                ARouter.getInstance()\n                        .build(BaseConstants.LIBRARY_MY_KNIFE)\n                        .navigation());\n        getBinding().btnFingerprint.setOnClickListener(v ->\n                ARouter.getInstance()\n                        .build(BaseConstants.LIBRARY_FINGERPRIINT_IDENTIFY)\n                        .navigation());\n        getBinding().btnWorkManager.setOnClickListener(v ->\n                ARouter.getInstance()\n                        .build(BaseConstants.LIBRARY_WORK_MANAGER)\n                        .navigation());\n        SerializeActivity.Monster monster = new SerializeActivity.Monster(\"Monster01\", 1,\n                new SerializeActivity.Weapon(\"Weapon01\"), new Date(), new SerializeActivity.Grade(1));\n        getBinding().btnSerial.setOnClickListener(v ->\n                ARouter.getInstance()\n                        .build(BaseConstants.LIBRARY_SERIAL)\n                        .withParcelable(BaseConstants.LIBRARY_SERIAL_ARG_MONSTER, monster)\n                        .navigation());\n        getBinding().btnHandler.setOnClickListener(v ->\n                ARouter.getInstance()\n                        .build(BaseConstants.LIBRARY_HANDLER)\n                        .navigation());\n        getBinding().btnTimeZone.setOnClickListener(v -> {\n            Calendar cal = Calendar.getInstance();\n            int offset = cal.get(Calendar.ZONE_OFFSET);\n            ToastUtils.makeToast(String.valueOf(offset / 3600000));\n        });\n    }\n\n    public void imageCompress(View view) {\n        ARouter.getInstance()\n                .build(BaseConstants.LIBRARY_COMPRESS)\n                .navigation();\n    }\n\n    private void configToolbar() {\n        Toolbar toolbar = getBinding().barLayout.toolbar;\n        toolbar.setBackgroundResource(R.color.light_theme_background);\n        setSupportActionBar(toolbar);\n        ActionBar actionBar = getSupportActionBar();\n        if (actionBar != null) {\n            actionBar.setTitle(R.string.menu_item_title_4);\n            actionBar.setSubtitle(R.string.menu_item_desc_4);\n            actionBar.setDisplayHomeAsUpEnabled(true);\n        }\n    }\n\n    @Override\n    public boolean onOptionsItemSelected(MenuItem item) {\n        switch (item.getItemId()) {\n            case android.R.id.home:\n                super.onBackPressed();\n                break;\n        }\n        return super.onOptionsItemSelected(item);\n    }\n}\n"
  },
  {
    "path": "libraries/src/main/java/me/shouheng/libraries/ModuleLibraryApp.java",
    "content": "package me.shouheng.libraries;\n\nimport com.alibaba.android.arouter.launcher.ARouter;\n\nimport me.shouheng.commons.BaseApplication;\n\n/**\n * @author shouh\n * @version $Id: ModuleGuokrApp, v 0.1 2018/6/6 22:30 shouh Exp$\n */\npublic class ModuleLibraryApp extends BaseApplication {\n\n    private static ModuleLibraryApp application;\n\n    public static ModuleLibraryApp getContext() {\n        return application;\n    }\n\n    @Override\n    public void onCreate() {\n        super.onCreate();\n        application = this;\n\n        ARouter.init(this);\n    }\n}\n"
  },
  {
    "path": "libraries/src/main/java/me/shouheng/libraries/MyKnifeActivity.java",
    "content": "package me.shouheng.libraries;\n\nimport android.os.Bundle;\nimport android.widget.TextView;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.ToastUtils;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.knife.api.MyKnife;\nimport me.shouheng.libraries.databinding.ActivityMyKnifeBinding;\n\n/**\n * @Warn Test my knife activity, delete the annotations if you set this module as lib instead of application. */\n@Route(path = BaseConstants.LIBRARY_MY_KNIFE)\npublic class MyKnifeActivity extends CommonActivity<ActivityMyKnifeBinding> {\n\n//    @BindView(id = R.id.tv)\n    public TextView textView;\n\n//    @OnClick(ids = {R.id.btn})\n    public void OnClick() {\n        ToastUtils.makeToast(\"OnClick\");\n    }\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_my_knife;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        MyKnife.bind(this);\n        textView.setText(\"This is MyKnife demo!\");\n    }\n}\n"
  },
  {
    "path": "libraries/src/main/java/me/shouheng/libraries/TimberActivity.java",
    "content": "package me.shouheng.libraries;\n\nimport android.os.Bundle;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n\nimport java.text.SimpleDateFormat;\nimport java.util.Date;\nimport java.util.Locale;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.libraries.databinding.ActivityTimberBinding;\nimport timber.log.Timber;\n\n@Route(path = BaseConstants.LIBRARY_TIMBER)\npublic class TimberActivity extends CommonActivity<ActivityTimberBinding> {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_timber;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        getBinding().btnLogV.setOnClickListener(v -> Timber.v(getBinding().et.getText().toString()));\n        getBinding().btnLogD.setOnClickListener(v -> Timber.d(getBinding().et.getText().toString()));\n        getBinding().btnLogE.setOnClickListener(v -> Timber.e(getBinding().et.getText().toString()));\n        getBinding().btnLogW.setOnClickListener(v -> Timber.w(getBinding().et.getText().toString()));\n        getBinding().btnLogDate.setOnClickListener(v ->\n                Timber.d(\"当前时间： %s\", new SimpleDateFormat(\"YYYY-MM-dd\", Locale.getDefault()).format(new Date())));\n    }\n}\n"
  },
  {
    "path": "libraries/src/main/java/me/shouheng/libraries/eventbus/EventBusActivity1.java",
    "content": "package me.shouheng.libraries.eventbus;\n\nimport android.os.Bundle;\nimport androidx.appcompat.app.ActionBar;\nimport androidx.appcompat.widget.Toolbar;\nimport android.view.MenuItem;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.alibaba.android.arouter.launcher.ARouter;\n\nimport org.greenrobot.eventbus.EventBus;\nimport org.greenrobot.eventbus.Subscribe;\nimport org.greenrobot.eventbus.ThreadMode;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.libraries.R;\nimport me.shouheng.libraries.databinding.ActivityEventBus1Binding;\n\n@Route(path = BaseConstants.LIBRARY_EVENT_BUS_ACTIVITY1)\npublic class EventBusActivity1 extends CommonActivity<ActivityEventBus1Binding> {\n\n    private boolean stopDelivery = false;\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_event_bus1;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        configToolbar();\n\n        getBinding().btnReg.setOnClickListener(v ->\n                EventBus.getDefault().register(this));\n        getBinding().btnNav2.setOnClickListener( v ->\n                ARouter.getInstance()\n                        .build(BaseConstants.LIBRARY_EVENT_BUS_ACTIVITY2)\n                        .navigation());\n        getBinding().btnStop.setOnClickListener(v -> stopDelivery = true);\n    }\n\n    private void configToolbar() {\n        Toolbar toolbar = getBinding().barLayout.toolbar;\n        toolbar.setBackgroundResource(R.color.light_theme_background);\n        setSupportActionBar(toolbar);\n        ActionBar actionBar = getSupportActionBar();\n        if (actionBar != null) {\n            actionBar.setTitle(\"EventBus\");\n            actionBar.setSubtitle(\"Demo activity 1\");\n            actionBar.setDisplayHomeAsUpEnabled(true);\n        }\n    }\n\n    @Override\n    public boolean onOptionsItemSelected(MenuItem item) {\n        switch (item.getItemId()) {\n            case android.R.id.home:\n                super.onBackPressed();\n                break;\n        }\n        return super.onOptionsItemSelected(item);\n    }\n\n    @Override\n    protected void onDestroy() {\n        super.onDestroy();\n        EventBus.getDefault().unregister(this);\n    }\n\n    @Subscribe(threadMode = ThreadMode.POSTING, priority = 0)\n    public void onGetMessage(MessageWrap message) {\n        getBinding().tvMessage.setText(message.message);\n    }\n\n    @Subscribe(threadMode = ThreadMode.POSTING, sticky = true, priority = 1)\n    public void onGetStickyEvent(MessageWrap message) {\n        String txt = \"Sticky event: \" + message.message;\n        getBinding().tvStickyMessage.setText(txt);\n        if (stopDelivery) {\n            EventBus.getDefault().cancelEventDelivery(message);\n        }\n    }\n}\n"
  },
  {
    "path": "libraries/src/main/java/me/shouheng/libraries/eventbus/EventBusActivity2.java",
    "content": "package me.shouheng.libraries.eventbus;\n\nimport android.os.Bundle;\nimport androidx.appcompat.app.ActionBar;\nimport androidx.appcompat.widget.Toolbar;\nimport android.view.MenuItem;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n\nimport org.greenrobot.eventbus.EventBus;\nimport org.greenrobot.eventbus.Subscribe;\nimport org.greenrobot.eventbus.ThreadMode;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.ToastUtils;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.libraries.R;\nimport me.shouheng.libraries.databinding.ActivityEventBus2Binding;\n\n@Route(path = BaseConstants.LIBRARY_EVENT_BUS_ACTIVITY2)\npublic class EventBusActivity2 extends CommonActivity<ActivityEventBus2Binding> {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_event_bus2;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        configToolbar();\n\n        EventBus.getDefault().register(this);\n\n        getBinding().btnPublish.setOnClickListener(v -> publishContent());\n        getBinding().btnPublishAndFinish.setOnClickListener(v -> {\n            publishContent();\n            finish();\n        });\n        getBinding().btnPublishSticky.setOnClickListener(v -> publishStickyontent());\n    }\n\n    private void publishContent() {\n        String msg = getBinding().etMessage.getText().toString();\n        EventBus.getDefault().post(MessageWrap.getInstance(msg));\n        ToastUtils.makeToast(\"Published : \" + msg);\n    }\n\n    private void publishStickyontent() {\n        String msg = getBinding().etMessage.getText().toString();\n        EventBus.getDefault().postSticky(MessageWrap.getInstance(msg));\n        ToastUtils.makeToast(\"Published : \" + msg);\n    }\n\n    private void configToolbar() {\n        Toolbar toolbar = getBinding().barLayout.toolbar;\n        toolbar.setBackgroundResource(R.color.light_theme_background);\n        setSupportActionBar(toolbar);\n        ActionBar actionBar = getSupportActionBar();\n        if (actionBar != null) {\n            actionBar.setTitle(\"EventBus\");\n            actionBar.setSubtitle(\"Demo activity 2\");\n            actionBar.setDisplayHomeAsUpEnabled(true);\n        }\n    }\n\n    @Override\n    public boolean onOptionsItemSelected(MenuItem item) {\n        switch (item.getItemId()) {\n            case android.R.id.home:\n                super.onBackPressed();\n                break;\n        }\n        return super.onOptionsItemSelected(item);\n    }\n\n    @Subscribe(threadMode = ThreadMode.MAIN)\n    public void onGetMessage(MessageWrap message) {\n        getBinding().tvMessage.setText(message.message);\n    }\n\n    @Override\n    protected void onDestroy() {\n        super.onDestroy();\n        EventBus.getDefault().unregister(this);\n    }\n}\n"
  },
  {
    "path": "libraries/src/main/java/me/shouheng/libraries/eventbus/MessageWrap.java",
    "content": "package me.shouheng.libraries.eventbus;\n\n/**\n * @author shouh\n * @version $Id: MessageWrap, v 0.1 2018/8/5 15:18 shouh Exp$\n */\npublic class MessageWrap {\n\n    public final String message;\n\n    public static MessageWrap getInstance(String message) {\n        return new MessageWrap(message);\n    }\n\n    private MessageWrap(String message) {\n        this.message = message;\n    }\n}\n"
  },
  {
    "path": "libraries/src/main/java/me/shouheng/libraries/handler/FileRecognizeTask.java",
    "content": "package me.shouheng.libraries.handler;\n\nimport android.app.IntentService;\nimport android.content.Context;\nimport android.content.Intent;\n\nimport me.shouheng.commons.tools.LogUtils;\n\n/**\n * @author shouh\n * @version $Id: FileRecognizeTask, v 0.1 2018/11/4 23:40 shouh Exp$\n */\npublic class FileRecognizeTask extends IntentService {\n\n    public static void start(Context context) {\n        Intent intent = new Intent(context, FileRecognizeTask.class);\n        context.startService(intent);\n    }\n\n    public FileRecognizeTask() {\n        super(\"FileRecognizeTask\");\n    }\n\n\n    @Override\n    protected void onHandleIntent(@androidx.annotation.Nullable Intent intent) {\n        // do something\n        LogUtils.d(\"=========================================\");\n    }\n}\n"
  },
  {
    "path": "libraries/src/main/java/me/shouheng/libraries/handler/HandlerActivity.java",
    "content": "package me.shouheng.libraries.handler;\n\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.HandlerThread;\nimport android.os.Looper;\nimport android.os.Message;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.LogUtils;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.libraries.R;\nimport me.shouheng.libraries.databinding.ActivityHandlerBinding;\n\n/**\n * Created by WngShhng on 2018/11/1.\n */\n@Route(path = BaseConstants.LIBRARY_HANDLER)\npublic class HandlerActivity extends CommonActivity<ActivityHandlerBinding> {\n\n    private final static int SAY_HELLO = 1;\n\n    private static Handler handler = new Handler() {\n        @Override\n        public void handleMessage(Message msg) {\n            switch (msg.what) {\n                case SAY_HELLO:\n                    LogUtils.d(\"Hello!\");\n                    break;\n            }\n        }\n    };\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_handler;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        LogUtils.d(\"========开始一个任务，将在2秒之后执行========\");\n        new Handler().postDelayed(() -> LogUtils.d(\"========任务开始执行========\"), 2000);\n\n        LogUtils.d(\"=========开始一个线程========\");\n        new Thread(() -> {\n            try {\n                // new Handler(); // 会因为该线程中没有对应的 Looper 而发生异常\n                Thread.sleep(2000);\n                new Handler(Looper.getMainLooper())\n                        .post(() -> getBinding().tv.setText(\"任务执行完毕，主线程更新UI\"));\n//                handler.post(() -> getBinding().tv.setText(\"任务执行完毕，主线程更新UI\"));\n            } catch (InterruptedException e) {\n                e.printStackTrace();\n            }\n        }).start();\n\n        new Thread(() -> {\n            LogUtils.d(\"+++++++++\" + Thread.currentThread());\n            Looper.prepare();\n            new Handler().post(() -> LogUtils.d(\"+++++++++\" + Thread.currentThread()));\n            Looper.loop();\n        }).start();\n\n        Message message = Message.obtain(handler);\n        message.what = SAY_HELLO;\n        message.sendToTarget();\n        // or below\n//        Message message = Message.obtain();\n//        message.what = SAY_HELLO;\n//        handler.sendMessage(message);\n\n        // HandlerThread demo\n        HandlerThread handlerThread = new HandlerThread(\"MyHandlerThread\");\n        handlerThread.start();\n\n        // IntentService demo\n        FileRecognizeTask.start(this);\n    }\n}\n"
  },
  {
    "path": "libraries/src/main/java/me/shouheng/libraries/image/ClipPictureActivity.java",
    "content": "package me.shouheng.libraries.image;\n\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapFactory;\nimport android.os.Bundle;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.ToastUtils;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.libraries.R;\nimport me.shouheng.libraries.databinding.ActivityClipPictureBinding;\n\n/**\n * Created by WngShhng on 2018/8/21.*/\n@Route(path = BaseConstants.LIBRARY_CLIP_PIC)\npublic class ClipPictureActivity extends CommonActivity<ActivityClipPictureBinding> {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_clip_picture;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        BitmapFactory.Options options = new BitmapFactory.Options();\n        options.inSampleSize = 1;\n        options.inScaled = false;\n        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.raw.test_pic, options);\n        ToastUtils.makeToast(\"w:\" + bitmap.getWidth() + \" h:\" + bitmap.getHeight());\n        Bitmap cliped = Bitmap.createBitmap(bitmap, 54, 217, 125, 28);\n        getBinding().ivPic.setImageBitmap(cliped);\n    }\n}\n"
  },
  {
    "path": "libraries/src/main/java/me/shouheng/libraries/image/ImageCompressActivity.java",
    "content": "package me.shouheng.libraries.image;\n\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapFactory;\nimport android.graphics.BitmapFactory.Options;\nimport android.graphics.Matrix;\nimport android.os.Bundle;\nimport android.os.Environment;\nimport android.util.Log;\nimport android.util.TypedValue;\nimport android.view.View;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.OutputStream;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.PalmUtils;\nimport me.shouheng.commons.tools.ToastUtils;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.libraries.R;\nimport me.shouheng.libraries.databinding.ActivityImageCompressBinding;\n\n@Route(path = BaseConstants.LIBRARY_COMPRESS)\npublic class ImageCompressActivity extends CommonActivity<ActivityImageCompressBinding> {\n\n    private static final String TAG = \"ImageCompressActivity\";\n\n    private static final String COMPRESS_FILE_NAME = \"compress.jpg\";\n    private static final String SCALE_COMPRESS_FILE_NAME = \"scale_compress.jpg\";\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_image_compress;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        // empty\n    }\n\n    /**\n     * 临近采样图片压缩\n     *\n     * @param view v\n     * @throws IOException exception\n     */\n    public void compressAlgorithm(View view) throws IOException {\n        File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), COMPRESS_FILE_NAME);\n        StringBuilder sb = new StringBuilder(PalmUtils.getStringCompact(R.string.libraries_compress_compress));\n        sb.append(\"：\\n\");\n\n        BitmapFactory.Options options = getOriginalOptions(R.raw.ice_land);\n        sb.append(String.format(PalmUtils.getStringCompact(R.string.libraries_compress_compress_original), options.outWidth, options.outHeight));\n        sb.append(\"\\n\");\n\n        // 执行图片压缩：采样率 2，压缩的质量 75\n        ByteArrayOutputStream stream = new ByteArrayOutputStream();\n        options.inSampleSize = 2;\n        options.inJustDecodeBounds = false;\n        options.inScaled = false; // 需要设置这个参数，那么要根据资源的类型进行判断吗？\n        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.raw.ice_land, options);\n        Log.d(TAG, options.outWidth + \" \" + options.outHeight); // 从这里看的结果确实是加载了一半\n        Log.d(TAG, bitmap.getWidth() + \" \" + bitmap.getHeight()); // TODO Error!\n        bitmap.compress(Bitmap.CompressFormat.JPEG, 75, stream);\n        Log.d(TAG, bitmap.getWidth() + \" \" + bitmap.getHeight());\n        bitmap.recycle();\n        saveToFileSystem(file, stream); // 最终写出的数据有问题\n\n        ToastUtils.makeToast(\"Success saved to \" + file.getPath());\n        BitmapFactory.Options retOptions = getOriginalOptions(file.getPath());\n        sb.append(String.format(PalmUtils.getStringCompact(R.string.libraries_compress_compress_result), retOptions.outWidth, retOptions.outHeight));\n        getBinding().tvDisplay.setText(sb.toString());\n    }\n\n    /**\n     * 双线性采样\n     *\n     * @param view view\n     * @throws IOException IOException\n     */\n    public void scaleCompressAlgorithm(View view) throws IOException {\n        File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), SCALE_COMPRESS_FILE_NAME);\n        StringBuilder sb = new StringBuilder(PalmUtils.getStringCompact(R.string.libraries_compress_scale));\n        sb.append(\"：\\n\");\n\n        BitmapFactory.Options options = getOriginalOptions(R.raw.ice_land);\n        int originalWidth = options.outWidth, originalHeight = options.outHeight;\n        sb.append(String.format(PalmUtils.getStringCompact(R.string.libraries_compress_compress_original), options.outWidth, options.outHeight));\n        sb.append(\"\\n\");\n\n        options.inJustDecodeBounds = false;\n        options.inSampleSize = 2;\n        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.raw.ice_land, options);\n        Log.d(TAG, options.outWidth + \" \" + options.outHeight);\n        Matrix matrix = new Matrix();\n        float scale = 1200f / originalWidth;\n        matrix.setScale(scale, scale);\n        Bitmap scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, originalWidth, originalHeight, matrix, true);\n        saveToFileSystem(file, scaledBitmap);\n\n        ToastUtils.makeToast(\"Success saved to \" + file.getPath());\n        BitmapFactory.Options retOptions = getOriginalOptions(file.getPath());\n        sb.append(String.format(PalmUtils.getStringCompact(R.string.libraries_compress_compress_result), retOptions.outWidth, retOptions.outHeight));\n        getBinding().tvDisplay.setText(sb.toString());\n    }\n\n    // region private methods\n    private BitmapFactory.Options getOriginalOptions(int resId) {\n        BitmapFactory.Options options = new Options();\n        options.inJustDecodeBounds = true;\n        options.inSampleSize = 1;\n        BitmapFactory.decodeResource(getResources(), resId, options);\n        return options;\n    }\n\n    private BitmapFactory.Options getOriginalOptions(String saveFilePath) {\n        BitmapFactory.Options retOptions = new Options();\n        retOptions.inJustDecodeBounds = true;\n        retOptions.inSampleSize = 1;\n        BitmapFactory.decodeFile(saveFilePath, retOptions);\n        return retOptions;\n    }\n\n    private void saveToFileSystem(File file, ByteArrayOutputStream stream) throws IOException {\n        OutputStream fos = new FileOutputStream(file);\n        fos.write(stream.toByteArray());\n        fos.flush();\n        fos.close();\n        stream.close();\n    }\n\n    private void saveToFileSystem(File file, Bitmap bitmap) throws IOException {\n        ByteArrayOutputStream stream = new ByteArrayOutputStream();\n        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);\n        saveToFileSystem(file, stream);\n    }\n\n    private Bitmap rotatingImage(Bitmap bitmap, int angle) {\n        Matrix matrix = new Matrix();\n        matrix.postRotate(angle);\n        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);\n    }\n    // endregion\n\n}\n"
  },
  {
    "path": "libraries/src/main/java/me/shouheng/libraries/rxjava/DemoFragment.java",
    "content": "package me.shouheng.libraries.rxjava;\n\nimport android.os.Bundle;\nimport androidx.fragment.app.Fragment;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.alibaba.android.arouter.launcher.ARouter;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.LogUtils;\nimport me.shouheng.commons.view.fragment.CommonFragment;\nimport me.shouheng.libraries.R;\nimport me.shouheng.libraries.databinding.FragmentDemoBinding;\n\n/**\n * Created by WngShhng on 2018/10/19.\n */\n@Route(path = BaseConstants.LIBRARY_FRAGMENT_DEMO)\npublic class DemoFragment extends CommonFragment<FragmentDemoBinding> {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.fragment_demo;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        boolean hasChild = getArguments().getBoolean(BaseConstants.LIBRARY_FRAGMENT_DEMO_HAS_CHILD);\n        if (hasChild) {\n            getChildFragmentManager()\n                    .beginTransaction()\n                    .replace(R.id.fragment_container, (Fragment) ARouter.getInstance()\n                            .build(BaseConstants.LIBRARY_FRAGMENT_DEMO)\n                            .withBoolean(BaseConstants.LIBRARY_FRAGMENT_DEMO_HAS_CHILD, false)\n                            .navigation())\n                    .commit();\n        }\n        addSubscription(RxMessage.class, rxMessage ->\n                LogUtils.d(\"++++++++++++++++++++++ DemoFragment(hasChild:\" + hasChild + \"): 接受到消息 \" + rxMessage.message + \"！\"));\n    }\n}\n"
  },
  {
    "path": "libraries/src/main/java/me/shouheng/libraries/rxjava/RxBusActivity.java",
    "content": "package me.shouheng.libraries.rxjava;\n\nimport android.os.Bundle;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.libraries.R;\nimport me.shouheng.libraries.databinding.ActivityRxBusBinding;\n\n/**\n * Created by WngShhng on 2018/8/17.\n */\n@Route(path = BaseConstants.LIBRARY_RX_JAVA_BUS)\npublic class RxBusActivity extends CommonActivity<ActivityRxBusBinding> {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_rx_bus;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        getBinding().btnSendEvent.setOnClickListener(v -> {\n            postEvent(new RxMessage(\"Hello world!\"));\n        });\n    }\n}\n"
  },
  {
    "path": "libraries/src/main/java/me/shouheng/libraries/rxjava/RxJavaActivity.java",
    "content": "package me.shouheng.libraries.rxjava;\n\nimport android.os.Bundle;\nimport androidx.fragment.app.Fragment;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.alibaba.android.arouter.launcher.ARouter;\n\nimport io.reactivex.Observable;\nimport io.reactivex.ObservableOnSubscribe;\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.FragmentHelper;\nimport me.shouheng.commons.tools.LogUtils;\nimport me.shouheng.commons.tools.ToastUtils;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.libraries.R;\nimport me.shouheng.libraries.databinding.ActivityRxjavaBinding;\n\n/**\n * @author shouh\n * @version $Id: RxJavaActivity, v 0.1 2018/8/7 8:22 shouh Exp$\n */\n@Route(path = BaseConstants.LIBRARY_RX_JAVA)\npublic class RxJavaActivity extends CommonActivity<ActivityRxjavaBinding> {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_rxjava;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        getBinding().btn1.setOnClickListener(v ->\n                Observable.create((ObservableOnSubscribe<String>) emitter -> {\n                    String str = getBinding().et.getText().toString();\n                    emitter.onNext(str);\n//                emitter.onError(new Exception(\"Exception\"));\n//                emitter.onComplete();\n                }).subscribe(ToastUtils::makeToast));\n        getBinding().btn2.setOnClickListener(v -> Observable.just(1,2,3,4).subscribe(LogUtils::d));\n        getBinding().btnRxBus.setOnClickListener(v ->\n                ARouter.getInstance()\n                        .build(BaseConstants.LIBRARY_RX_JAVA_BUS)\n                        .navigation());\n        addSubscription(RxMessage.class, rxMessage -> {\n            ToastUtils.makeToast(rxMessage.message);\n            LogUtils.d(\"++++++++++++++++++++++ RxJavaActivity: 接受到消息 \" + rxMessage.message + \"！\");\n        });\n        FragmentHelper.replace(this,\n                (Fragment) ARouter.getInstance()\n                        .build(BaseConstants.LIBRARY_FRAGMENT_DEMO)\n                        .withBoolean(BaseConstants.LIBRARY_FRAGMENT_DEMO_HAS_CHILD, true)\n                        .navigation(),\n                R.id.fragment_container);\n    }\n}\n"
  },
  {
    "path": "libraries/src/main/java/me/shouheng/libraries/rxjava/RxMessage.java",
    "content": "package me.shouheng.libraries.rxjava;\n\n/**\n * Created by WngShhng on 2018/8/17.*/\npublic class RxMessage {\n\n    public final String message;\n\n    RxMessage(String message) {\n        this.message = message;\n    }\n}\n"
  },
  {
    "path": "libraries/src/main/java/me/shouheng/libraries/serial/SerializeActivity.java",
    "content": "package me.shouheng.libraries.serial;\n\nimport android.os.Bundle;\nimport android.os.Parcel;\nimport android.os.Parcelable;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\n\nimport java.io.Serializable;\nimport java.lang.reflect.Array;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.libraries.R;\nimport me.shouheng.libraries.databinding.ActivitySerializeBinding;\nimport timber.log.Timber;\n\n/**\n * @author shouh\n * @version $Id: SerializeActivity, v 0.1 2018/10/21 17:58 shouh Exp$\n */\n@Route(path = BaseConstants.LIBRARY_SERIAL)\npublic class SerializeActivity extends CommonActivity<ActivitySerializeBinding> {\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_serialize;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        /*----------------------------------Serializable-------------------------------------*/\n        SerializeUtils.setStudent(new Student(\"Student.01\",\n                12,\n                new Role(\"Role01\"),\n                () -> \"do whatever\"));\n        Student student = SerializeUtils.getStudent();\n        assert student != null;\n        String strStu = student.toString() + \"\\n\\n\" + student.i.doSomething();\n        getBinding().tvStudent.setText(strStu);\n\n        /*----------------------------------------Parcelable--------------------------------------------*/\n        Monster monster = getIntent().getParcelableExtra(BaseConstants.LIBRARY_SERIAL_ARG_MONSTER);\n        getBinding().tvMonster.setText(monster.toString());\n    }\n\n    public static class Student implements Serializable {\n        final String name;\n        final int age;\n\n        /**\n         * 内部的字段也应该实现序列化接口，才能进行正确序列化\n         */\n        final Role role;\n\n        /**\n         * 接口也必须实现 Serializable 接口\n         */\n        final IInterface i;\n\n        public Student(String name, int age, Role role, IInterface i) {\n            this.name = name;\n            this.age = age;\n            this.role = role;\n            this.i = i;\n        }\n\n        @Override\n        public String toString() {\n            return \"Student{\" +\n                    \"name='\" + name + '\\'' +\n                    \", age=\" + age +\n                    \", role=\" + role +\n                    '}';\n        }\n    }\n\n    public static class Role implements Serializable {\n\n        final String name;\n\n        public Role(String name) {\n            this.name = name;\n        }\n\n        @Override\n        public String toString() {\n            return \"Role{\" +\n                    \"name='\" + name + '\\'' +\n                    '}';\n        }\n    }\n\n    public interface IInterface extends Serializable {\n        String doSomething();\n    }\n\n    // region 直接使用接口的实现方式\n    /*\n\n    public static class Monster implements Parcelable {\n        final String name;\n        final int age;\n        final Weapon weapon;\n        final Date birthday;\n\n        public Monster(String name, int age, Weapon weapon, Date birthday) {\n            this.name = name;\n            this.age = age;\n            this.weapon = weapon;\n            this.birthday = birthday;\n        }\n\n        Monster(Parcel in) {\n            name = in.readString();\n            age = in.readInt();\n            weapon = in.readParcelable(Weapon.class.getClassLoader());\n            birthday = (Date) in.readSerializable();\n        }\n\n        public static final Creator<Monster> CREATOR = new Creator<Monster>() {\n            @Override\n            public Monster createFromParcel(Parcel in) {\n                return new Monster(in);\n            }\n\n            @Override\n            public Monster[] newArray(int size) {\n                return new Monster[size];\n            }\n        };\n\n        @Override\n        public int describeContents() {\n            return 0;\n        }\n\n        @Override\n        public void writeToParcel(Parcel dest, int flags) {\n            dest.writeString(name);\n            dest.writeInt(age);\n            dest.writeParcelable(weapon, 0);\n            dest.writeSerializable(birthday);\n        }\n\n        @Override\n        public String toString() {\n            return \"Monster{\" +\n                    \"name='\" + name + '\\'' +\n                    \", age=\" + age +\n                    \", weapon=\" + weapon +\n                    \", birthday=\" + birthday +\n                    '}';\n        }\n    }\n\n    public static class Weapon implements Parcelable {\n        final String name;\n\n        public Weapon(String name) {\n            this.name = name;\n        }\n\n        Weapon(Parcel in) {\n            name = in.readString();\n        }\n\n        public static final Creator<Weapon> CREATOR = new Creator<Weapon>() {\n            @Override\n            public Weapon createFromParcel(Parcel in) {\n                return new Weapon(in);\n            }\n\n            @Override\n            public Weapon[] newArray(int size) {\n                return new Weapon[size];\n            }\n        };\n\n        @Override\n        public String toString() {\n            return \"Weapon{\" +\n                    \"name='\" + name + '\\'' +\n                    '}';\n        }\n\n        @Override\n        public int describeContents() {\n            return 0;\n        }\n\n        @Override\n        public void writeToParcel(Parcel dest, int flags) {\n            dest.writeString(name);\n        }\n    }\n\n    */\n    // endregion\n\n    public static class Monster extends BaseParcelable<Monster> {\n\n        public static final Creator<Monster> CREATOR = CreatorFactory.getCreator(Monster.class);\n\n        String name;\n        int age;\n        Weapon weapon;\n        Date birthday;\n        Grade grade;\n\n        public Monster(String name, int age, Weapon weapon, Date birthday, Grade grade) {\n            this.name = name;\n            this.age = age;\n            this.weapon = weapon;\n            this.birthday = birthday;\n            this.grade = grade;\n        }\n\n        public Monster(Parcel in) {\n            super(in);\n        }\n\n        @Override\n        public String toString() {\n            return \"Monster{\" +\n                    \"name='\" + name + '\\'' +\n                    \", age=\" + age +\n                    \", weapon=\" + weapon +\n                    \", birthday=\" + birthday +\n                    \", grade=\" + grade +\n                    \"}\";\n        }\n    }\n\n    public static class Weapon extends BaseParcelable {\n\n        public static final Creator<Weapon> CREATOR = CreatorFactory.getCreator(Weapon.class);\n\n        String name;\n\n        public Weapon(String name) {\n            this.name = name;\n        }\n\n        /**\n         * 需要时 public 的，并且字段不能是 final 的\n         *\n         * @param in\n         */\n        public Weapon(Parcel in) {\n            super(in);\n        }\n\n        @Override\n        public String toString() {\n            return \"Weapon{\" +\n                    \"name='\" + name + '\\'' +\n                    '}';\n        }\n    }\n\n    public static class Grade {\n        int grade;\n\n        public Grade(int grade) {\n            this.grade = grade;\n        }\n\n        @Override\n        public String toString() {\n            return \"Grade{\" +\n                    \"grade=\" + grade +\n                    '}';\n        }\n    }\n\n    // TODO There are many available methods for simplifying the usage of Parcelable, most are implemented by auto-generating codes\n    public static abstract class BaseParcelable<T> implements Parcelable {\n\n        protected BaseParcelable() { }\n\n        protected BaseParcelable(Parcel in) {\n            // TODO 父类中的字段\n            Field[] fields = getClass().getDeclaredFields();\n            Class<?> fieldType;\n            CreatorFactory.TypeHandler<?> typeHandler;\n            try {\n                for (Field field : fields) {\n                    fieldType = field.getType();\n                    /*------------------------------使用类型处理器---------------------------------*/\n                    if ((typeHandler = CreatorFactory.handlerMap.get(fieldType)) != null) {\n                        field.set(this, typeHandler.read(in));\n                        continue;\n                    }\n                    /*------------------------------默认数据类型--------------------------------*/\n                    if (fieldType == String.class) {\n                        field.set(this, in.readString());\n                    } else if (fieldType == byte.class || fieldType == Byte.class) {\n                        field.set(this, in.readByte());\n                    } else if (fieldType == short.class || fieldType == Short.class) {\n                        field.set(this, in.readInt());\n                    } else if (fieldType == int.class || fieldType == Integer.class) {\n                        field.set(this, in.readInt());\n                    } else if (fieldType == long.class || fieldType == Long.class) {\n                        field.set(this, in.readLong());\n                    } else if (fieldType == float.class || fieldType == Float.class) {\n                        field.set(this, in.readFloat());\n                    } else if (fieldType == double.class || fieldType == Double.class) {\n                        field.set(this, in.readDouble());\n                    } else if (fieldType == boolean.class || fieldType == Boolean.class) {\n                        field.set(this, in.readInt() == 1);\n                    } else if (Serializable.class.isAssignableFrom(fieldType)) {\n                        field.set(this, in.readSerializable());\n                    } else if (Parcelable.class.isAssignableFrom(fieldType)) {\n                        field.set(this, in.readParcelable(fieldType.getClassLoader()));\n                    }\n                }\n            } catch (IllegalAccessException e) {\n                Timber.e(e);\n            }\n        }\n\n        @Override\n        public int describeContents() {\n            return 0;\n        }\n\n        @Override\n        public void writeToParcel(Parcel dest, int flags) {\n            Field[] fields = getClass().getDeclaredFields();\n            Class<?> fieldType;\n            CreatorFactory.TypeHandler<Object> typeHandler;\n            try {\n                for (Field field : fields) {\n                    fieldType = field.getType();\n                    /*------------------------------使用类型处理器---------------------------------*/\n                    if ((typeHandler = (CreatorFactory.TypeHandler<Object>) CreatorFactory.handlerMap.get(fieldType)) != null) {\n                        typeHandler.write(dest, field.get(this));\n                        continue;\n                    }\n                    /*------------------------------默认数据类型--------------------------------*/\n                    if (fieldType == String.class) {\n                        dest.writeString((String) field.get(this));\n                    } else if (fieldType == byte.class || fieldType == Byte.class) {\n                        dest.writeByte((Byte) field.get(this));\n                    } else if (fieldType == short.class || fieldType == Short.class) {\n                        dest.writeInt((Short) field.get(this));\n                    } else if (fieldType == int.class || fieldType == Integer.class) {\n                        dest.writeInt((Integer) field.get(this));\n                    } else if (fieldType == long.class || fieldType == Long.class) {\n                        dest.writeLong((Long) field.get(this));\n                    } else if (fieldType == float.class || fieldType == Float.class) {\n                        dest.writeFloat((Float) field.get(this));\n                    } else if (fieldType == double.class || fieldType == Double.class) {\n                        dest.writeDouble((Double) field.get(this));\n                    } else if (fieldType == boolean.class || fieldType == Boolean.class) {\n                        dest.writeInt((Boolean) field.get(this) ? 1 : 0);\n                    } else if (Serializable.class.isAssignableFrom(fieldType)) {\n                        dest.writeSerializable((Serializable) field.get(this));\n                    } else if (Parcelable.class.isAssignableFrom(fieldType)) {\n                        dest.writeParcelable((Parcelable) field.get(this), 0);\n                    }\n                }\n            } catch (IllegalAccessException e) {\n                Timber.e(e);\n            }\n        }\n    }\n\n    public static class CreatorFactory {\n\n        public static Map<Class<?>, TypeHandler<?>> handlerMap = new HashMap<>();\n\n        /*-----------------------自定义的类型处理器在这里添加进去------------------------*/\n        static {\n            addTypeHandler(Date.class, new TypeHandler<Date>() {\n                @Override\n                public void write(Parcel in, Date date) {\n                    in.writeLong(date.getTime());\n                }\n\n                @Override\n                public Date read(Parcel in) {\n                    return new Date(in.readLong());\n                }\n            });\n            addTypeHandler(Grade.class, new TypeHandler<Grade>() {\n                @Override\n                public void write(Parcel in, Grade grade) {\n                    in.writeInt(grade.grade);\n                }\n\n                @Override\n                public Grade read(Parcel in) {\n                    return new Grade(in.readInt());\n                }\n            });\n        }\n\n        /**\n         * 获取指定类型的创建器\n         *\n         * @param type 类型\n         * @param <T> 类型\n         * @return 创建器\n         */\n        public static <T extends BaseParcelable> Parcelable.Creator<T> getCreator(Class<T> type) {\n            return new Parcelable.Creator<T>() {\n                @Override\n                public T createFromParcel(Parcel in) {\n                    try {\n                        Constructor<T> c = type.getConstructor(Parcel.class);\n                        return c.newInstance(in);\n                    } catch (IllegalAccessException e) {\n                        Timber.e(e);\n                    } catch (InstantiationException e) {\n                        Timber.e(e);\n                    } catch (NoSuchMethodException e) {\n                        Timber.e(e);\n                    } catch (InvocationTargetException e) {\n                        Timber.e(e);\n                    }\n                    throw new RuntimeException(\"illegal\");\n                }\n\n                @Override\n                public T[] newArray(int size) {\n                    return (T[]) Array.newInstance(type, size);\n                }\n            };\n        }\n\n        /**\n         * 类型处理器\n         *\n         * @param <T>\n         */\n        public interface TypeHandler<T> {\n            void write(Parcel in, T t);\n            T read(Parcel in);\n        }\n\n        /**\n         * 添加指定类型的类型处理器\n         *\n         * @param type 类型\n         * @param typeHandler 类型处理器\n         * @param <T> 类型\n         */\n        public static <T> void addTypeHandler(Class<T> type, TypeHandler<T> typeHandler) {\n            handlerMap.put(type, typeHandler);\n        }\n    }\n}\n"
  },
  {
    "path": "libraries/src/main/java/me/shouheng/libraries/serial/SerializeUtils.java",
    "content": "package me.shouheng.libraries.serial;\n\nimport android.content.Context;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\nimport me.shouheng.commons.BaseApplication;\nimport timber.log.Timber;\n\n/**\n * @author shouh\n * @version $Id: SerializeUtils, v 0.1 2018/10/21 18:03 shouh Exp$\n */\npublic class SerializeUtils {\n\n    private final static char[] hexArray = \"0123456789ABCDEF\".toCharArray();\n\n    public static String bytesToHex(byte[] bytes) {\n        char[] hexChars = new char[bytes.length * 2];\n        for ( int j = 0; j < bytes.length; j++ ) {\n            int v = bytes[j] & 0xFF;\n            hexChars[j * 2] = hexArray[v >>> 4];\n            hexChars[j * 2 + 1] = hexArray[v & 0x0F];\n        }\n        return new String(hexChars);\n    }\n\n    public static byte[] hexStringToByteArray(String s) {\n        int len = s.length();\n        byte[] data = new byte[len / 2];\n        for (int i = 0; i < len; i += 2) {\n            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)\n                    + Character.digit(s.charAt(i+1), 16));\n        }\n        return data;\n    }\n\n    private static Object convertFromString(String text) {\n        byte[] bytes = hexStringToByteArray(text);\n        ObjectInputStream in = null;\n\n        try {\n            in = new ObjectInputStream(new ByteArrayInputStream(bytes));\n            return in.readObject();\n        } catch (Exception e) {\n            Timber.e(e);\n        } finally {\n            if (in != null) {\n                try {\n                    in.close();\n                } catch (IOException e) {\n                    Timber.e(e);\n                }\n            }\n        }\n        return null;\n    }\n\n    private static String convertToString(Object obj) {\n        ByteArrayOutputStream bos = new ByteArrayOutputStream();\n        //StringWriter stringWriter = new StringWriter();\n        ObjectOutputStream out = null;\n        if (obj == null) {\n            return null;\n        }\n\n        try {\n            out = new ObjectOutputStream(bos);\n            out.writeObject(obj);\n            out.flush();\n            return bytesToHex(bos.toByteArray());\n        } catch (IOException e) {\n            Timber.e(e);\n        } finally {\n            if (out != null) {\n                try {\n                    out.close();\n                } catch (IOException e) {\n                    Timber.e(e);\n                }\n            }\n        }\n        return null;\n    }\n\n    public static void putString(String key, String text) {\n        Context context = BaseApplication.getContext();\n        context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE)\n                .edit()\n                .putString(key, text)\n                .apply();\n    }\n\n    public static String getString(String key, String defaultValue) {\n        Context context = BaseApplication.getContext();\n        return context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE)\n                .getString(key, defaultValue);\n    }\n\n    public static void remove(String key) {\n        Context context = BaseApplication.getContext();\n        context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE)\n                .edit()\n                .remove(key)\n                .apply();\n    }\n\n    public static void setStudent(SerializeActivity.Student user) {\n        if (user != null) {\n            String text = convertToString(user);\n            if (text != null) {\n                putString(\"student\", text);\n            }\n        } else {\n            remove(\"student\");\n        }\n    }\n\n    public static SerializeActivity.Student getStudent() {\n        String text = getString(\"student\", null);\n        if (text != null) {\n            return (SerializeActivity.Student) convertFromString(text);\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "libraries/src/main/java/me/shouheng/libraries/workmanager/PeriodicTask.java",
    "content": "package me.shouheng.libraries.workmanager;\n\nimport android.content.Context;\nimport androidx.annotation.NonNull;\n\nimport androidx.work.Worker;\nimport androidx.work.WorkerParameters;\nimport io.reactivex.Observable;\nimport io.reactivex.disposables.Disposable;\nimport me.shouheng.commons.tools.LogUtils;\n\n/**\n * Created by WngShhng on 2018/9/13.\n */\npublic class PeriodicTask extends Worker {\n\n    private static int repeatCountStatic = 0;\n\n    private int repeatCount = 0;\n\n    public PeriodicTask(@NonNull Context context, @NonNull WorkerParameters workerParams) {\n        super(context, workerParams);\n    }\n\n    @NonNull\n    @Override\n    public Result doWork() {\n        repeatCount++;\n        repeatCountStatic++;\n        LogUtils.d(\"PeriodicTask \" + repeatCount + \"/\" + repeatCountStatic + \". begins ......\");\n        LogUtils.d(Thread.currentThread());\n        Disposable disposable = Observable.range(1, 10).subscribe(integer -> {\n            System.out.println(Thread.currentThread());\n            System.out.println(\"PeriodicTask \" + repeatCount + \"/\" + repeatCountStatic + \" : \" + integer);\n            Thread.sleep(1000);\n        });\n        return Result.SUCCESS;\n    }\n}\n"
  },
  {
    "path": "libraries/src/main/java/me/shouheng/libraries/workmanager/SingleTask.java",
    "content": "package me.shouheng.libraries.workmanager;\n\nimport android.content.Context;\nimport androidx.annotation.NonNull;\n\nimport androidx.work.Worker;\nimport androidx.work.WorkerParameters;\nimport io.reactivex.Observable;\nimport io.reactivex.disposables.Disposable;\nimport me.shouheng.commons.tools.LogUtils;\n\n/**\n * Created by WngShhng on 2018/9/13.\n */\npublic class SingleTask extends Worker {\n\n    public SingleTask(@NonNull Context context, @NonNull WorkerParameters workerParams) {\n        super(context, workerParams);\n    }\n\n    @NonNull\n    @Override\n    public Result doWork() {\n        LogUtils.d(\"SingleTask 1. begins ......\");\n        LogUtils.d(Thread.currentThread());\n        Disposable disposable = Observable.range(1, 10).subscribe(integer -> {\n            System.out.println(Thread.currentThread());\n            System.out.println(\"SingleTask 1 : \" + integer);\n            Thread.sleep(1000);\n        });\n        return Result.SUCCESS;\n    }\n}\n"
  },
  {
    "path": "libraries/src/main/java/me/shouheng/libraries/workmanager/SingleTask2.java",
    "content": "package me.shouheng.libraries.workmanager;\n\nimport android.content.Context;\nimport androidx.annotation.NonNull;\n\nimport androidx.work.Worker;\nimport androidx.work.WorkerParameters;\nimport io.reactivex.Observable;\nimport io.reactivex.disposables.Disposable;\nimport me.shouheng.commons.tools.LogUtils;\n\n/**\n * Created by WngShhng on 2018/9/13.\n */\npublic class SingleTask2 extends Worker {\n\n    public SingleTask2(@NonNull Context context, @NonNull WorkerParameters workerParams) {\n        super(context, workerParams);\n    }\n\n    @NonNull\n    @Override\n    public Result doWork() {\n        LogUtils.d(\"SingleTask 2. begins ......\");\n        LogUtils.d(Thread.currentThread());\n        Disposable disposable = Observable.range(1, 10).subscribe(integer -> {\n            System.out.println(Thread.currentThread());\n            System.out.println(\"SingleTask 2 : \" + integer);\n            Thread.sleep(1000);\n        });\n        return Result.SUCCESS;\n    }\n}\n"
  },
  {
    "path": "libraries/src/main/java/me/shouheng/libraries/workmanager/WorkManagerActivity.java",
    "content": "package me.shouheng.libraries.workmanager;\n\nimport android.os.Bundle;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.google.common.util.concurrent.ListenableFuture;\n\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\n\nimport androidx.lifecycle.LiveData;\nimport androidx.work.Constraints;\nimport androidx.work.ExistingWorkPolicy;\nimport androidx.work.OneTimeWorkRequest;\nimport androidx.work.OneTimeWorkRequest.Builder;\nimport androidx.work.PeriodicWorkRequest;\nimport androidx.work.WorkContinuation;\nimport androidx.work.WorkManager;\nimport androidx.work.WorkStatus;\nimport androidx.work.impl.utils.futures.SettableFuture;\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.libraries.R;\nimport me.shouheng.libraries.databinding.ActivityWorkManagerBinding;\n\n/**\n * Created by WngShhng on 2018/9/13.\n */\n@Route(path = BaseConstants.LIBRARY_WORK_MANAGER)\npublic class WorkManagerActivity extends CommonActivity<ActivityWorkManagerBinding> {\n\n    private WorkManager workManager;\n    private ListenableFuture<List<WorkStatus>> workStatuses;\n    private String TAG_OUTPUT = \"tag_output\";\n    private String SINGLE_TASK_NAME = \"SINGLE_TASK\";\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_work_manager;\n    }\n\n    /**\n     * 任何一个任务在触发之后会按照指定的规则运行，如果后台被清理掉，那么这些任务会暂停，并被清理掉\n     * 下次打开应用的时候会立即触发并执行这些任务：\n     * 1.没执行完毕的单次任务会被重新执行，像下面的两个依次执行的任务，当1执行完毕，2在执行中的时候\n     * 清理了后台，那么重新打开应用的时候会把2重新执行一遍，1不会被执行了（因为本身处在队列中，执行完就不在队列中了）；\n     * 2.如果是连续的任务，那么当后台被清理掉，并重新打开的时候，会立即重新执行一遍任务。\n     *\n     * @param savedInstanceState savedInstanceState\n     */\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        workManager = WorkManager.getInstance();\n        workStatuses = workManager.getStatusesByTag(TAG_OUTPUT);\n\n        getBinding().btnStartSingle.setOnClickListener(v -> {\n            WorkContinuation continuation = workManager.beginUniqueWork(SINGLE_TASK_NAME,\n                    ExistingWorkPolicy.REPLACE,\n                    OneTimeWorkRequest.from(SingleTask.class));\n            // 构建一个任务\n            Constraints constraints = new Constraints.Builder().build();\n            OneTimeWorkRequest.Builder builder = new Builder(SingleTask2.class).setConstraints(constraints);\n            // 注意赋值操作\n            continuation = continuation.then(builder.build());\n            // 开始后台工作\n            continuation.enqueue();\n        });\n\n        getBinding().btnCancelSingle.setOnClickListener(v -> workManager.cancelUniqueWork(SINGLE_TASK_NAME));\n\n        getBinding().btnStartPeriodic.setOnClickListener(v -> {\n            PeriodicWorkRequest periodicWork = new PeriodicWorkRequest.Builder(PeriodicTask.class, 15, TimeUnit.MINUTES).build();\n            workManager.enqueue(periodicWork);\n        });\n\n        getBinding().btnCancelPeriodic.setOnClickListener(v -> {\n\n        });\n    }\n}\n"
  },
  {
    "path": "libraries/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillColor=\"#26A69A\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n"
  },
  {
    "path": "libraries/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillType=\"evenOdd\"\n        android:pathData=\"M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"78.5885\"\n                android:endY=\"90.9159\"\n                android:startX=\"48.7653\"\n                android:startY=\"61.0927\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        android:pathData=\"M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\" />\n</vector>\n"
  },
  {
    "path": "libraries/src/main/res/layout/activity_clip_picture.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <LinearLayout\n        android:orientation=\"vertical\"\n        android:fitsSystemWindows=\"true\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <androidx.appcompat.widget.AppCompatImageView\n            android:id=\"@+id/iv_pic\"\n            android:scaleType=\"fitXY\"\n            android:layout_width=\"200dp\"\n            android:layout_height=\"40dp\" />\n\n    </LinearLayout>\n\n</layout>"
  },
  {
    "path": "libraries/src/main/res/layout/activity_event_bus1.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    tools:context=\".eventbus.EventBusActivity1\">\n\n    <RelativeLayout\n        android:fitsSystemWindows=\"true\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <include android:id=\"@+id/bar_layout\" layout=\"@layout/layout_toolbar\"/>\n\n        <androidx.core.widget.NestedScrollView\n            android:layout_below=\"@id/bar_layout\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\">\n\n            <LinearLayout\n                android:orientation=\"vertical\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\">\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn_reg\"\n                    android:text=\"@string/library_register_event_bus\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn_nav_2\"\n                    android:text=\"@string/library_navigation_to_2\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn_stop\"\n                    android:text=\"@string/event_bus_stop_delivery\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatTextView\n                    android:id=\"@+id/tv_message\"\n                    android:textStyle=\"bold\"\n                    android:layout_gravity=\"center\"\n                    tools:text=\"Message\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatTextView\n                    android:id=\"@+id/tv_sticky_message\"\n                    android:textStyle=\"bold\"\n                    android:layout_gravity=\"center\"\n                    tools:text=\"Message\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\" />\n\n            </LinearLayout>\n\n        </androidx.core.widget.NestedScrollView>\n\n        <View android:layout_below=\"@id/bar_layout\"\n            android:background=\"@drawable/bg_toolbar_shade\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"5dp\"/>\n\n    </RelativeLayout>\n\n</layout>"
  },
  {
    "path": "libraries/src/main/res/layout/activity_event_bus2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    tools:context=\".eventbus.EventBusActivity1\">\n\n    <RelativeLayout\n        android:fitsSystemWindows=\"true\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <include android:id=\"@+id/bar_layout\" layout=\"@layout/layout_toolbar\"/>\n\n        <androidx.core.widget.NestedScrollView\n            android:layout_below=\"@id/bar_layout\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\">\n\n            <LinearLayout\n                android:orientation=\"vertical\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\">\n\n                <androidx.appcompat.widget.AppCompatEditText\n                    android:id=\"@+id/et_message\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn_publish\"\n                    android:text=\"@string/text_publish\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn_publish_and_finish\"\n                    android:text=\"@string/text_publish_and_finish\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn_publish_sticky\"\n                    android:text=\"@string/text_publish_sticky_event\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatTextView\n                    android:id=\"@+id/tv_message\"\n                    android:textStyle=\"bold\"\n                    android:layout_gravity=\"center\"\n                    tools:text=\"Message\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\" />\n\n            </LinearLayout>\n\n        </androidx.core.widget.NestedScrollView>\n\n        <View android:layout_below=\"@id/bar_layout\"\n            android:background=\"@drawable/bg_toolbar_shade\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"5dp\"/>\n\n    </RelativeLayout>\n\n</layout>"
  },
  {
    "path": "libraries/src/main/res/layout/activity_fingerprint_identify.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <LinearLayout\n        android:fitsSystemWindows=\"true\"\n        android:orientation=\"vertical\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <include android:id=\"@+id/bar_layout\" layout=\"@layout/layout_toolbar\"/>\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_identify\"\n            android:text=\"Begin Identify\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatTextView\n            android:id=\"@+id/tv_result\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n    </LinearLayout>\n\n</layout>"
  },
  {
    "path": "libraries/src/main/res/layout/activity_handler.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <LinearLayout\n        android:orientation=\"vertical\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <androidx.appcompat.widget.AppCompatTextView\n            android:id=\"@+id/tv\"\n            android:gravity=\"center\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\" />\n\n    </LinearLayout>\n\n</layout>"
  },
  {
    "path": "libraries/src/main/res/layout/activity_image_compress.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <androidx.constraintlayout.widget.ConstraintLayout\n        android:fitsSystemWindows=\"true\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_compress\"\n            android:text=\"@string/libraries_compress_compress\"\n            android:onClick=\"compressAlgorithm\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_scale\"\n            app:layout_constraintTop_toBottomOf=\"@id/btn_compress\"\n            android:text=\"@string/libraries_compress_scale\"\n            android:onClick=\"scaleCompressAlgorithm\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatImageView\n            android:id=\"@+id/iv_display\"\n            android:padding=\"10dp\"\n            app:layout_constraintTop_toBottomOf=\"@id/btn_scale\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatTextView\n            android:id=\"@+id/tv_display\"\n            android:textSize=\"16sp\"\n            android:padding=\"10dp\"\n            app:layout_constraintTop_toBottomOf=\"@id/iv_display\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n    </androidx.constraintlayout.widget.ConstraintLayout>\n\n</layout>"
  },
  {
    "path": "libraries/src/main/res/layout/activity_menu.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    tools:context=\".MenuActivity\">\n\n    <RelativeLayout\n        android:fitsSystemWindows=\"true\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <include android:id=\"@+id/bar_layout\" layout=\"@layout/layout_toolbar\"/>\n\n        <androidx.core.widget.NestedScrollView\n            android:layout_below=\"@id/bar_layout\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\">\n\n            <LinearLayout\n                android:orientation=\"vertical\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\">\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/bnt_event_bus\"\n                    android:text=\"@string/library_menu_event_bus\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn_rxjava\"\n                    android:text=\"@string/library_menu_rxjava\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn_clip\"\n                    android:text=\"@string/library_menu_clip\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn_timber\"\n                    android:text=\"@string/library_menu_timber\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn_my_knife\"\n                    android:text=\"@string/library_menu_my_knife\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn_fingerprint\"\n                    android:text=\"@string/libraries_finger\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn_work_manager\"\n                    android:text=\"@string/libraries_workmanager\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn_serial\"\n                    android:text=\"@string/libraries_serialize\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn_handler\"\n                    android:text=\"@string/libraries_handler\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn_time_zone\"\n                    android:text=\"@string/libraries_timezone\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn_compress\"\n                    android:text=\"@string/libraries_compress\"\n                    android:onClick=\"imageCompress\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n            </LinearLayout>\n\n        </androidx.core.widget.NestedScrollView>\n\n        <View android:layout_below=\"@id/bar_layout\"\n            android:background=\"@drawable/bg_toolbar_shade\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"5dp\"/>\n\n    </RelativeLayout>\n\n</layout>"
  },
  {
    "path": "libraries/src/main/res/layout/activity_my_knife.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    tools:context=\".MyKnifeActivity\">\n\n    <LinearLayout\n        android:fitsSystemWindows=\"true\"\n        android:orientation=\"vertical\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <TextView\n            android:id=\"@+id/tv\"\n            android:textSize=\"20sp\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <Button\n            android:id=\"@+id/btn\"\n            android:text=\"OnClick Test\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n    </LinearLayout>\n\n</layout>"
  },
  {
    "path": "libraries/src/main/res/layout/activity_rx_bus.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout>\n\n    <LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:fitsSystemWindows=\"true\"\n        android:orientation=\"vertical\" android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_send_event\"\n            android:text=\"Send Event\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n    </LinearLayout>\n\n</layout>"
  },
  {
    "path": "libraries/src/main/res/layout/activity_rxjava.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <RelativeLayout\n        android:fitsSystemWindows=\"true\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <include android:id=\"@+id/bar_layout\" layout=\"@layout/layout_toolbar\"/>\n\n        <androidx.core.widget.NestedScrollView\n            android:layout_below=\"@id/bar_layout\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\">\n\n            <LinearLayout\n                android:orientation=\"vertical\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\">\n\n                <androidx.appcompat.widget.AppCompatEditText\n                    android:id=\"@+id/et\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"50dp\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn1\"\n                    android:text=\"Test 1\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn2\"\n                    android:text=\"Test 2\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <androidx.appcompat.widget.AppCompatButton\n                    android:id=\"@+id/btn_rx_bus\"\n                    android:text=\"Navigate to RxBus\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n\n                <FrameLayout\n                    android:id=\"@+id/fragment_container\"\n                    android:padding=\"10dp\"\n                    android:background=\"@android:color/holo_purple\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"200dp\">\n\n                </FrameLayout>\n\n            </LinearLayout>\n\n        </androidx.core.widget.NestedScrollView>\n\n        <View android:layout_below=\"@id/bar_layout\"\n            android:background=\"@drawable/bg_toolbar_shade\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"5dp\"/>\n\n    </RelativeLayout>\n\n</layout>"
  },
  {
    "path": "libraries/src/main/res/layout/activity_serialize.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <LinearLayout\n        android:fitsSystemWindows=\"true\"\n        android:orientation=\"vertical\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <androidx.appcompat.widget.AppCompatTextView\n            android:id=\"@+id/tv_student\"\n            android:padding=\"16dp\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatTextView\n            android:id=\"@+id/tv_monster\"\n            android:padding=\"16dp\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n    </LinearLayout>\n\n</layout>"
  },
  {
    "path": "libraries/src/main/res/layout/activity_timber.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    tools:context=\".TimberActivity\">\n\n    <LinearLayout\n        android:fitsSystemWindows=\"true\"\n        android:orientation=\"vertical\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <androidx.appcompat.widget.AppCompatEditText\n            android:id=\"@+id/et\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_log_v\"\n            android:text=\"Log V\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_log_d\"\n            android:text=\"Log D\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_log_w\"\n            android:text=\"Log W\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_log_e\"\n            android:text=\"Log E\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_log_date\"\n            android:text=\"Log Date\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n    </LinearLayout>\n\n</layout>"
  },
  {
    "path": "libraries/src/main/res/layout/activity_work_manager.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <LinearLayout\n        android:fitsSystemWindows=\"true\"\n        android:orientation=\"vertical\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_start_single\"\n            android:text=\"Start Single Task\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_cancel_single\"\n            android:text=\"Cancel Single Task\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_start_periodic\"\n            android:text=\"Start Periodic Task\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <androidx.appcompat.widget.AppCompatButton\n            android:id=\"@+id/btn_cancel_periodic\"\n            android:text=\"Cancel Periodic Task\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n    </LinearLayout>\n\n</layout>"
  },
  {
    "path": "libraries/src/main/res/layout/fragment_demo.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <FrameLayout\n        android:id=\"@+id/fragment_container\"\n        android:orientation=\"vertical\"\n        android:padding=\"10dp\"\n        android:background=\"@android:color/holo_red_dark\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"/>\n\n</layout>"
  },
  {
    "path": "libraries/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "libraries/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "libraries/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#FAFAFA</color>\n    <color name=\"colorPrimaryDark\">#FAFAFA</color>\n    <color name=\"colorAccent\">#0078FF</color>\n</resources>\n"
  },
  {
    "path": "libraries/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">libraries</string>\n</resources>\n"
  },
  {
    "path": "libraries/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.NoActionBar\">\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "live/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "live/build.gradle",
    "content": "println isLiveModuleApp.toBoolean()\n\nif (isLiveModuleApp.toBoolean()) {\n    apply plugin: 'com.android.application'\n} else {\n    apply plugin: 'com.android.library'\n}\n\nandroid {\n    compileSdkVersion rootProject.ext.compileSdkVersion\n    defaultConfig {\n        minSdkVersion rootProject.ext.minSdkVersion\n        targetSdkVersion rootProject.ext.targetSdkVersion\n        versionCode 1\n        versionName \"1.0\"\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n        javaCompileOptions {\n            annotationProcessorOptions {\n                arguments = [ moduleName : project.getName() ]\n            }\n        }\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n    // use data binding\n    dataBinding {\n        enabled = true\n    }\n    // use java 8 language\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n    // use external libs folder\n    sourceSets {\n        main {\n            jniLibs.srcDirs = ['libs']\n            if (isLiveModuleApp.toBoolean()) {\n                manifest.srcFile \"src/main/debug/AndroidManifest.xml\"\n            } else {\n                manifest.srcFile \"src/main/AndroidManifest.xml\"\n            }\n        }\n    }\n}\n\ndependencies {\n    implementation fileTree(dir: 'libs', include: ['*.jar'])\n    testImplementation 'junit:junit:4.12'\n    androidTestImplementation 'androidx.test:runner:1.1.0'\n    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'\n    // banner\n    implementation 'com.bigkoo:convenientbanner:2.0.5'\n    // router\n    annotationProcessor 'com.alibaba:arouter-compiler:1.1.4'\n    // projects\n    implementation project(':commons')\n}\n"
  },
  {
    "path": "live/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "live/src/androidTest/java/me/shouheng/live/ExampleInstrumentedTest.java",
    "content": "package me.shouheng.live;\n\nimport android.content.Context;\nimport androidx.test.InstrumentationRegistry;\nimport androidx.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.assertEquals;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"me.shouheng.live\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "live/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"me.shouheng.live\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />\n    <uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\" />\n    <uses-permission android:name=\"android.permission.READ_PHONE_STATE\" />\n    <uses-permission android:name=\"android.permission.WAKE_LOCK\" />\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\">\n\n        <activity android:name=\".view.activity.LiveActivity\"/>\n\n        <activity android:name=\".view.activity.LiveRoomActivity\"/>\n\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "live/src/main/debug/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"me.shouheng.live\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />\n    <uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\" />\n    <uses-permission android:name=\"android.permission.READ_PHONE_STATE\" />\n    <uses-permission android:name=\"android.permission.WAKE_LOCK\" />\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\"\n        android:name=\".LiveModuleApp\">\n\n        <activity android:name=\".view.activity.LiveActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n\n        <activity android:name=\".view.activity.LiveRoomActivity\"/>\n\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "live/src/main/java/me/shouheng/live/LiveModuleApp.java",
    "content": "package me.shouheng.live;\n\nimport com.alibaba.android.arouter.launcher.ARouter;\n\nimport me.shouheng.commons.BaseApplication;\n\n/**\n * @author shouh\n * @version $Id: LiveModuleApp, v 0.1 2018/7/30 20:40 shouh Exp$\n */\npublic class LiveModuleApp extends BaseApplication {\n\n    private static LiveModuleApp application;\n\n    public static LiveModuleApp getContext() {\n        return application;\n    }\n\n    @Override\n    public void onCreate() {\n        super.onCreate();\n        application = this;\n\n        ARouter.init(this);\n    }\n}"
  },
  {
    "path": "live/src/main/java/me/shouheng/live/common/DecimalFormatUtil.java",
    "content": "package me.shouheng.live.common;\n\nimport java.text.DecimalFormat;\n\npublic class DecimalFormatUtil {\n\n    private static final DecimalFormat decimalFormat = new DecimalFormat();\n\n    public static String formatW(int vaule){\n        if(vaule >= 10000){\n            float l = vaule / 10000.0f;\n            return format(l,\"#.#'W'\");\n        }\n       return String.valueOf(vaule);\n    }\n\n    public static String format(float vaule, String pattern){\n        decimalFormat.applyPattern(pattern);\n        return decimalFormat.format(vaule);\n    }\n}\n"
  },
  {
    "path": "live/src/main/java/me/shouheng/live/common/widget/FlutteringLayout.java",
    "content": "package me.shouheng.live.common.widget;\n\nimport android.animation.Animator;\nimport android.animation.AnimatorListenerAdapter;\nimport android.animation.AnimatorSet;\nimport android.animation.ObjectAnimator;\nimport android.animation.TypeEvaluator;\nimport android.animation.ValueAnimator;\nimport android.content.Context;\nimport android.content.res.TypedArray;\nimport android.graphics.PointF;\nimport androidx.annotation.AttrRes;\nimport androidx.annotation.DrawableRes;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport android.util.AttributeSet;\nimport android.view.View;\nimport android.view.animation.AccelerateDecelerateInterpolator;\nimport android.view.animation.AccelerateInterpolator;\nimport android.view.animation.BounceInterpolator;\nimport android.view.animation.DecelerateInterpolator;\nimport android.view.animation.Interpolator;\nimport android.view.animation.LinearInterpolator;\nimport android.view.animation.OvershootInterpolator;\nimport android.widget.ImageView;\nimport android.widget.RelativeLayout;\n\nimport java.util.Random;\n\nimport me.shouheng.live.R;\n\n/**\n * Created by wangshouheng on 2017/7/30.\n */\npublic class FlutteringLayout extends RelativeLayout {\n\n    /**\n     * 桃心\n     */\n    private int[] heartRes = new int[]{\n            R.drawable.resource_heart0,R.drawable.resource_heart1,R.drawable.resource_heart2,\n            R.drawable.resource_heart3,R.drawable.resource_heart3,R.drawable.resource_heart5,\n            R.drawable.resource_heart6,R.drawable.resource_heart7,R.drawable.resource_heart8,\n            R.drawable.resource_heart9,R.drawable.resource_heart10\n    };\n\n    /**\n     * 插补器\n     */\n    private Interpolator[] interpolators = new Interpolator[]{\n            new LinearInterpolator(),new AccelerateInterpolator(),\n            new DecelerateInterpolator(),new AccelerateDecelerateInterpolator(),\n            new BounceInterpolator(),new OvershootInterpolator()\n    };\n\n    private int mWidth,mHeight;\n\n    private Random mRandom;\n\n    /**\n     * 进入动画持续时间\n     */\n    private int mEnterDuration = 300;\n    /**\n     * 动画持续时间\n     */\n    private int mDuration = 3000;\n    /**\n     * 桃心的缩放比例\n     */\n    private float mScale = 1.0f;\n\n    private LayoutParams mParams;\n\n    /**\n     * 是否是相同大小（如果是则只计算一次）\n     */\n    private boolean mIsSameSize = true;\n\n    private PointF mStartPointF;\n\n    public FlutteringLayout(@NonNull Context context) {\n        this(context,null);\n    }\n\n    public FlutteringLayout(@NonNull Context context, @Nullable AttributeSet attrs) {\n        this(context, attrs,0);\n    }\n\n    public FlutteringLayout(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {\n        super(context, attrs, defStyleAttr);\n        init(context,attrs);\n    }\n\n    private void init(Context context,AttributeSet attrs){\n\n        mRandom = new Random();\n\n        mStartPointF = new PointF();\n\n        mParams = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);\n        mParams.addRule(ALIGN_PARENT_BOTTOM,TRUE);\n        mParams.addRule(CENTER_HORIZONTAL,TRUE);\n\n        TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.FlutteringLayout);\n        mEnterDuration = a.getInt(R.styleable.FlutteringLayout_enter_duration,mEnterDuration);\n        mDuration = a.getInt(R.styleable.FlutteringLayout_duration,mDuration);\n        mScale = a.getFloat(R.styleable.FlutteringLayout_scale,mScale);\n        mIsSameSize = a.getBoolean(R.styleable.FlutteringLayout_same_size,mIsSameSize);\n\n        a.recycle();\n\n    }\n\n\n    @Override\n    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {\n        super.onMeasure(widthMeasureSpec, heightMeasureSpec);\n        //测量后的宽高\n        mWidth  = getMeasuredWidth();\n        mHeight = getMeasuredHeight();\n\n    }\n\n    /**\n     * 添加桃心\n     */\n    public void addHeart() {\n\n        ImageView iv = getHeartView(randomHeartResource());\n        addView(iv);\n        updateStartPointF(iv);\n\n        Animator animator = getAnimator(iv);\n        animator.addListener(new EndAnimatorListener(iv));\n        animator.start();\n\n    }\n\n    /**\n     * 获取一个桃心\n     * @param resId\n     * @return\n     */\n    private ImageView getHeartView(@DrawableRes int resId){\n        ImageView iv = new ImageView(getContext());\n        iv.setLayoutParams(mParams);\n        iv.setImageResource(resId);\n        return iv;\n    }\n\n\n    /**\n     * 飘心入场动画\n     * @param target\n     * @return\n     */\n    private AnimatorSet getEnterAnimator(View target){\n\n        ObjectAnimator scaleX = ObjectAnimator.ofFloat(target,View.SCALE_X,0.1f,mScale);\n        ObjectAnimator scaleY = ObjectAnimator.ofFloat(target,View.SCALE_Y,0.1f,mScale);\n        ObjectAnimator alpha = ObjectAnimator.ofFloat(target,View.ALPHA,0.1f,1.0f);\n\n        AnimatorSet animatorSet = new AnimatorSet();\n        animatorSet.playTogether(scaleX,scaleY,alpha);\n        animatorSet.setInterpolator(new LinearInterpolator());\n        animatorSet.setDuration(mEnterDuration);\n\n        return animatorSet;\n    }\n\n\n    /**\n     * 贝塞尔曲线动画\n     * @param target\n     * @return\n     */\n    private ValueAnimator getBezierCurveAnimator(final View target){\n\n        //贝塞尔曲线中间的两个点\n        final PointF pointf1 = randomPointF(3.0f);\n        final PointF pointf2 = randomPointF(1.5f);\n\n        // 传入  起点 和 终点\n        ValueAnimator valueAnimator = ValueAnimator.ofObject(new TypeEvaluator<PointF>(){\n            @Override\n            public PointF evaluate(float fraction, PointF startValue, PointF endValue) {\n\n                //三次方贝塞尔曲线 逻辑 通过四个点确定一条三次方贝塞尔曲线\n                float timeLeft = 1.0f - fraction;\n                PointF pointF = new PointF();\n                pointF.x = (float) (startValue.x * Math.pow(timeLeft,3) + 3 * pointf1.x  * fraction * Math.pow(timeLeft,2)\n                        + 3 * pointf2.x * Math.pow(fraction,2) * timeLeft + endValue.x * Math.pow(fraction,3));\n\n                pointF.y = (float) (startValue.y * Math.pow(timeLeft,3) + 3 * pointf1.y * fraction * Math.pow(timeLeft,2)\n                        + 3 * pointf2.y * Math.pow(fraction,2) * timeLeft + endValue.y * Math.pow(fraction,3));\n                return pointF;\n            }\n            //起点和终点\n        }, mStartPointF , new PointF(mRandom.nextInt(mWidth),0));\n\n        valueAnimator.setInterpolator(randomInterpolator());\n\n        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {\n            @Override\n            public void onAnimationUpdate(ValueAnimator animation) {\n                PointF pointF = (PointF) animation.getAnimatedValue();\n                //更新target的坐标\n                target.setX(pointF.x);\n                target.setY(pointF.y);\n                //透明度 从不透明到完全透明\n                target.setAlpha(1.0f - animation.getAnimatedFraction() * animation.getAnimatedFraction());\n            }\n        });\n        valueAnimator.setDuration(mDuration);\n\n        return valueAnimator;\n    }\n\n\n    private Animator getAnimator(View target){\n\n        AnimatorSet animatorSet = new AnimatorSet();\n        animatorSet.playSequentially(getEnterAnimator(target),getBezierCurveAnimator(target));\n        return animatorSet;\n\n    }\n\n    /**\n     * 测量\n     * @param target\n     */\n    private void makeMeasureSpec(View target){\n        int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);\n        target.measure(spec,spec);\n    }\n\n    /**\n     * 起点\n     * @param target\n     * @return\n     */\n    private void updateStartPointF(View target){\n\n        if(mStartPointF.x == 0 || mStartPointF.y == 0 || !mIsSameSize){\n            makeMeasureSpec(target);\n            int width = target.getMeasuredWidth();\n            int height = target.getMeasuredHeight();\n            mStartPointF.x = (mWidth + getPaddingLeft() - getPaddingRight() - width)/2;\n            mStartPointF.y = mHeight + getPaddingTop() - getPaddingBottom() - height;\n\n        }\n    }\n\n\n    /**\n     * 随机贝塞尔曲线中间的点\n     * @param scale\n     * @return\n     */\n    private PointF randomPointF(float scale){\n        PointF pointF = new PointF();\n        pointF.x = mRandom.nextInt(mWidth);\n        pointF.y = mRandom.nextInt(mHeight)/scale;\n\n        return pointF;\n    }\n\n    /**\n     * 随机一个插补器\n     * @return\n     */\n    private Interpolator randomInterpolator(){\n        return interpolators[mRandom.nextInt(interpolators.length)];\n    }\n\n    /**\n     * 随机一个桃心\n     * @return\n     */\n    private int randomHeartResource(){\n        return heartRes[mRandom.nextInt(heartRes.length)];\n    }\n\n    public int[] getHeartRes() {\n        return heartRes;\n    }\n\n    public void setHeartRes(int[] heartRes) {\n        this.heartRes = heartRes;\n    }\n\n    public Interpolator[] getInterpolators() {\n        return interpolators;\n    }\n\n    public void setInterpolators(Interpolator[] interpolators) {\n        this.interpolators = interpolators;\n    }\n\n    public int getEnterDuration() {\n        return mEnterDuration;\n    }\n\n    public void setEnterDuration(int enterDuration) {\n        this.mEnterDuration = enterDuration;\n    }\n\n    public int getDuration() {\n        return mDuration;\n    }\n\n    public void setDuration(int duration) {\n        this.mDuration = duration;\n    }\n\n    public float getScale() {\n        return mScale;\n    }\n\n    public void setScale(float scale) {\n        this.mScale = scale;\n    }\n\n    public void setHeartLayoutParams(LayoutParams params){\n        this.mParams = params;\n    }\n\n    public LayoutParams getHeartLayoutParams(){\n        return mParams;\n    }\n\n    public boolean isSameSize() {\n        return mIsSameSize;\n    }\n\n    public void setSameSize(boolean isSameSize) {\n        this.mIsSameSize = isSameSize;\n    }\n\n    private class EndAnimatorListener extends AnimatorListenerAdapter {\n\n        private View target;\n\n        public EndAnimatorListener(View target){\n            this.target = target;\n        }\n\n        @Override\n        public void onAnimationEnd(Animator animation) {\n            super.onAnimationEnd(animation);\n            //动画结束 移除target\n            removeView(target);\n        }\n    }\n}\n\n"
  },
  {
    "path": "live/src/main/java/me/shouheng/live/model/LiveService.java",
    "content": "package me.shouheng.live.model;\n\nimport io.reactivex.Observable;\nimport me.shouheng.live.model.data.AppStart;\nimport me.shouheng.live.model.data.Recommend;\nimport me.shouheng.live.model.data.Room;\nimport retrofit2.http.GET;\nimport retrofit2.http.Path;\n\n/**\n * @author shouh\n * @version $Id: LiveService, v 0.1 2018/6/8 21:49 shouh Exp$\n */\npublic interface LiveService {\n\n    @GET(\"json/page/app-data/info.json?v=3.0.1&os=1&ver=4\")\n    Observable<AppStart> getAppStartInfo();\n\n    @GET(\"json/app/index/recommend/list-android.json?v=3.0.1&os=1&ver=4\")\n    Observable<Recommend> getRecommend();\n\n    @GET(\"json/rooms/{uid}/info.json?v=3.0.1&os=1&ver=4\")\n    Observable<Room> enterRoom(@Path(\"uid\") String uid);\n}\n"
  },
  {
    "path": "live/src/main/java/me/shouheng/live/model/data/AppStart.java",
    "content": "package me.shouheng.live.model.data;\n\nimport com.google.gson.annotations.SerializedName;\n\nimport java.util.List;\n\npublic class AppStart {\n\n    /**\n     * id : 1781\n     * title : 一斟红酒液 养身有养心\n     * thumb : http://image.quanmin.tv/2ba4ded1b0d041856c974a8103f68cbcpng\n     * link : http://xmlife.smi170.com/resources/wap-shop/pages/goods_shopping.html?subjectId=399&title=Aglassofredwine&sourid=quanminzhibo\n     * create_at : 2017-03-12 23:50:03\n     * status : 1\n     * fk :\n     * subtitle :\n     * content :\n     * ext : {\"type\":\"html\",\"time\":\"3\",\"end_time\":1489507199}\n     * slot_id : 111\n     * priority : 0\n     */\n\n    private List<AndroidstartBean> androidstart;\n    /**\n     * id : 1309\n     * title :\n     * thumb : http://image.quanmin.tv/6152d95937023d6e730afb34f7aede01jpg\n     * link :\n     * create_at : 2016-07-26 18:21:10\n     * status : 1\n     * fk : 1980174\n     * subtitle :\n     * content :\n     * ext : {\"type\":\"play\"}\n     * slot_id : 113\n     * priority : 6\n     * link_object : {\"no\":\"1980174\",\"nick\":\"菠萝焕\",\"avatar\":\"http://a.img.shouyintv.cn/D46W101-normal\",\"follow\":\"76294\",\"uid\":\"1980174\",\"play_at\":\"2017-03-20 13:51:06\",\"screen\":0,\"views\":\"0\",\"intro\":\"符文天赋歌单在新浪微博:小焕亚索\",\"videoQuality\":\"3\",\"thumb\":\"http://image.quanmin.tv/6152d95937023d6e730afb34f7aede01jpg\",\"stream\":\"http://flv.quanmin.tv/live/1980174_L3.flv\",\"position\":\"\",\"announcement\":\"直播时间下午1点到晚上7点周日休息\",\"id\":\"100593\",\"video\":\"http://thumb.quanmin.tv/1980174.mp4?t=1490000100\",\"slug\":\"\",\"category_id\":\"1\",\"cover\":\"1980174-1490000275-760.jpg\",\"status\":\"2\",\"recommend_image\":\"http://image.quanmin.tv/5fa2a9871fec1c70c664dc7a00077879jpg\",\"weight\":\"0\",\"start_time\":\"1489989066.248\",\"check\":\"1\",\"priv\":\"0\",\"category_name\":\"英雄联盟\",\"title\":\"菠萝焕来呀互相伤害啊\",\"source\":\"ws\",\"last_play_at\":\"\",\"landscape\":\"1\",\"view\":\"82447\",\"app_shuffling_image\":\"http://image.quanmin.tv/3b87905359d4a53e217df6b3a04eadb1jpg\",\"categoryId\":\"1\",\"hidden\":false,\"play_status\":true}\n     */\n\n    @SerializedName(\"app-focus\")\n    private List<Banner> banners;\n\n    public List<AndroidstartBean> getAndroidstart() {\n        return androidstart;\n    }\n\n    public void setAndroidstart(List<AndroidstartBean> androidstart) {\n        this.androidstart = androidstart;\n    }\n\n    public List<Banner> getBanners() {\n        return banners;\n    }\n\n    public void setBanners(List<Banner> banners) {\n        this.banners = banners;\n    }\n\n    public static class AndroidstartBean {\n        private int id;\n        private String title;\n        private String thumb;\n        private String link;\n        private String create_at;\n        private int status;\n        private String fk;\n        private String subtitle;\n        private String content;\n        /**\n         * type : html\n         * time : 3\n         * end_time : 1489507199\n         */\n\n        private ExtBean ext;\n        private int slot_id;\n        private int priority;\n\n        public int getId() {\n            return id;\n        }\n\n        public void setId(int id) {\n            this.id = id;\n        }\n\n        public String getTitle() {\n            return title;\n        }\n\n        public void setTitle(String title) {\n            this.title = title;\n        }\n\n        public String getThumb() {\n            return thumb;\n        }\n\n        public void setThumb(String thumb) {\n            this.thumb = thumb;\n        }\n\n        public String getLink() {\n            return link;\n        }\n\n        public void setLink(String link) {\n            this.link = link;\n        }\n\n        public String getCreate_at() {\n            return create_at;\n        }\n\n        public void setCreate_at(String create_at) {\n            this.create_at = create_at;\n        }\n\n        public int getStatus() {\n            return status;\n        }\n\n        public void setStatus(int status) {\n            this.status = status;\n        }\n\n        public String getFk() {\n            return fk;\n        }\n\n        public void setFk(String fk) {\n            this.fk = fk;\n        }\n\n        public String getSubtitle() {\n            return subtitle;\n        }\n\n        public void setSubtitle(String subtitle) {\n            this.subtitle = subtitle;\n        }\n\n        public String getContent() {\n            return content;\n        }\n\n        public void setContent(String content) {\n            this.content = content;\n        }\n\n        public ExtBean getExt() {\n            return ext;\n        }\n\n        public void setExt(ExtBean ext) {\n            this.ext = ext;\n        }\n\n        public int getSlot_id() {\n            return slot_id;\n        }\n\n        public void setSlot_id(int slot_id) {\n            this.slot_id = slot_id;\n        }\n\n        public int getPriority() {\n            return priority;\n        }\n\n        public void setPriority(int priority) {\n            this.priority = priority;\n        }\n\n        public static class ExtBean {\n            private String type;\n            private String time;\n            private int end_time;\n\n            public String getType() {\n                return type;\n            }\n\n            public void setType(String type) {\n                this.type = type;\n            }\n\n            public String getTime() {\n                return time;\n            }\n\n            public void setTime(String time) {\n                this.time = time;\n            }\n\n            public int getEnd_time() {\n                return end_time;\n            }\n\n            public void setEnd_time(int end_time) {\n                this.end_time = end_time;\n            }\n\n            @Override\n            public String toString() {\n                return \"ExtBean{\" +\n                        \"type='\" + type + '\\'' +\n                        \", time='\" + time + '\\'' +\n                        \", end_time=\" + end_time +\n                        '}';\n            }\n        }\n\n        @Override\n        public String toString() {\n            return \"AndroidstartBean{\" +\n                    \"id=\" + id +\n                    \", title='\" + title + '\\'' +\n                    \", thumb='\" + thumb + '\\'' +\n                    \", link='\" + link + '\\'' +\n                    \", create_at='\" + create_at + '\\'' +\n                    \", status=\" + status +\n                    \", fk='\" + fk + '\\'' +\n                    \", subtitle='\" + subtitle + '\\'' +\n                    \", content='\" + content + '\\'' +\n                    \", ext=\" + ext +\n                    \", slot_id=\" + slot_id +\n                    \", priority=\" + priority +\n                    '}';\n        }\n    }\n\n    @Override\n    public String toString() {\n        return \"AppStart{\" +\n                \"androidstart=\" + androidstart +\n                \", banners=\" + banners +\n                '}';\n    }\n}\n"
  },
  {
    "path": "live/src/main/java/me/shouheng/live/model/data/Banner.java",
    "content": "package me.shouheng.live.model.data;\n\npublic class Banner {\n\n    /**\n     * id : 1309\n     * title :\n     * thumb : http://image.quanmin.tv/6152d95937023d6e730afb34f7aede01jpg\n     * link :\n     * create_at : 2016-07-26 18:21:10\n     * status : 1\n     * fk : 1980174\n     * subtitle :\n     * content :\n     * ext : {\"type\":\"play\"}\n     * slot_id : 113\n     * priority : 6\n     * link_object : {\"no\":\"1980174\",\"nick\":\"菠萝焕\",\"avatar\":\"http://a.img.shouyintv.cn/D46W101-normal\",\"follow\":\"76295\",\"uid\":\"1980174\",\"play_at\":\"2017-03-20 13:51:06\",\"screen\":0,\"views\":\"0\",\"intro\":\"符文天赋歌单在新浪微博:小焕亚索\",\"videoQuality\":\"3\",\"thumb\":\"http://image.quanmin.tv/6152d95937023d6e730afb34f7aede01jpg\",\"stream\":\"http://flv.quanmin.tv/live/1980174_L3.flv\",\"position\":\"\",\"announcement\":\"直播时间下午1点到晚上7点周日休息\",\"id\":\"100593\",\"video\":\"http://thumb.quanmin.tv/1980174.mp4?t=1489999200\",\"slug\":\"\",\"category_id\":\"1\",\"cover\":\"1980174-1489999436-214.jpg\",\"status\":\"2\",\"recommend_image\":\"http://image.quanmin.tv/5fa2a9871fec1c70c664dc7a00077879jpg\",\"weight\":\"0\",\"start_time\":\"1489989066.248\",\"check\":\"1\",\"priv\":\"0\",\"category_name\":\"英雄联盟\",\"title\":\"菠萝焕来呀互相伤害啊\",\"source\":\"ws\",\"last_play_at\":\"\",\"landscape\":\"1\",\"view\":\"82407\",\"app_shuffling_image\":\"http://image.quanmin.tv/3b87905359d4a53e217df6b3a04eadb1jpg\",\"categoryId\":\"1\",\"hidden\":false,\"play_status\":true}\n     */\n\n    private int id;\n    private String title;\n    private String thumb;\n    private String link;\n    private String create_at;\n    private int status;\n    private String fk;\n    private String subtitle;\n    private String content;\n    /**\n     * type : play\n     */\n\n    private ExtBean ext;\n    private int slot_id;\n    private int priority;\n    /**\n     * no : 1980174\n     * nick : 菠萝焕\n     * avatar : http://a.img.shouyintv.cn/D46W101-normal\n     * follow : 76295\n     * uid : 1980174\n     * play_at : 2017-03-20 13:51:06\n     * screen : 0\n     * views : 0\n     * intro : 符文天赋歌单在新浪微博:小焕亚索\n     * videoQuality : 3\n     * thumb : http://image.quanmin.tv/6152d95937023d6e730afb34f7aede01jpg\n     * stream : http://flv.quanmin.tv/live/1980174_L3.flv\n     * position :\n     * announcement : 直播时间下午1点到晚上7点周日休息\n     * id : 100593\n     * video : http://thumb.quanmin.tv/1980174.mp4?t=1489999200\n     * slug :\n     * category_id : 1\n     * cover : 1980174-1489999436-214.jpg\n     * status : 2\n     * recommend_image : http://image.quanmin.tv/5fa2a9871fec1c70c664dc7a00077879jpg\n     * weight : 0\n     * start_time : 1489989066.248\n     * check : 1\n     * priv : 0\n     * category_name : 英雄联盟\n     * title : 菠萝焕来呀互相伤害啊\n     * source : ws\n     * last_play_at :\n     * landscape : 1\n     * view : 82407\n     * app_shuffling_image : http://image.quanmin.tv/3b87905359d4a53e217df6b3a04eadb1jpg\n     * categoryId : 1\n     * hidden : false\n     * play_status : true\n     */\n\n    private LiveInfo link_object;\n\n    public int getId() {\n        return id;\n    }\n\n    public void setId(int id) {\n        this.id = id;\n    }\n\n    public String getTitle() {\n        return title;\n    }\n\n    public void setTitle(String title) {\n        this.title = title;\n    }\n\n    public String getThumb() {\n        return thumb;\n    }\n\n    public void setThumb(String thumb) {\n        this.thumb = thumb;\n    }\n\n    public String getLink() {\n        return link;\n    }\n\n    public void setLink(String link) {\n        this.link = link;\n    }\n\n    public String getCreate_at() {\n        return create_at;\n    }\n\n    public void setCreate_at(String create_at) {\n        this.create_at = create_at;\n    }\n\n    public int getStatus() {\n        return status;\n    }\n\n    public void setStatus(int status) {\n        this.status = status;\n    }\n\n    public String getFk() {\n        return fk;\n    }\n\n    public void setFk(String fk) {\n        this.fk = fk;\n    }\n\n    public String getSubtitle() {\n        return subtitle;\n    }\n\n    public void setSubtitle(String subtitle) {\n        this.subtitle = subtitle;\n    }\n\n    public String getContent() {\n        return content;\n    }\n\n    public void setContent(String content) {\n        this.content = content;\n    }\n\n    public ExtBean getExt() {\n        return ext;\n    }\n\n    public void setExt(ExtBean ext) {\n        this.ext = ext;\n    }\n\n    public int getSlot_id() {\n        return slot_id;\n    }\n\n    public void setSlot_id(int slot_id) {\n        this.slot_id = slot_id;\n    }\n\n    public int getPriority() {\n        return priority;\n    }\n\n    public void setPriority(int priority) {\n        this.priority = priority;\n    }\n\n    public LiveInfo getLink_object() {\n        return link_object;\n    }\n\n    public void setLink_object(LiveInfo link_object) {\n        this.link_object = link_object;\n    }\n\n    public boolean isRoom(){\n\n        if(getExt()!=null)\n            return \"play\".equals(getExt().getType());\n\n        return false;\n    }\n\n    public static class ExtBean {\n        private String type;\n\n        public String getType() {\n            return type;\n        }\n\n        public void setType(String type) {\n            this.type = type;\n        }\n\n        @Override\n        public String toString() {\n            return \"ExtBean{\" +\n                    \"type='\" + type + '\\'' +\n                    '}';\n        }\n    }\n\n    @Override\n    public String toString() {\n        return \"Banner{\" +\n                \"id=\" + id +\n                \", title='\" + title + '\\'' +\n                \", thumb='\" + thumb + '\\'' +\n                \", link='\" + link + '\\'' +\n                \", create_at='\" + create_at + '\\'' +\n                \", status=\" + status +\n                \", fk='\" + fk + '\\'' +\n                \", subtitle='\" + subtitle + '\\'' +\n                \", content='\" + content + '\\'' +\n                \", ext=\" + ext +\n                \", slot_id=\" + slot_id +\n                \", priority=\" + priority +\n                \", link_object=\" + link_object +\n                '}';\n    }\n}\n"
  },
  {
    "path": "live/src/main/java/me/shouheng/live/model/data/LiveInfo.java",
    "content": "package me.shouheng.live.model.data;\n\nimport me.shouheng.live.common.DecimalFormatUtil;\n\npublic class LiveInfo {\n\n    private String no;\n    private String nick;\n    private String avatar;\n    private int follow;\n    private String id;\n    private String uid;\n    private String title;\n    private String category_id;\n    private String slug;\n    private String intro;\n    private String announcement;\n    private String cover;\n    private String play_at;\n    private String last_play_at;\n    private String view;\n    private String status;\n    private String priv;\n    private String landscape;\n    private String position;\n    private String weight;\n    private String check;\n    private String recommend_image;\n    private String videoQuality;\n    private String category_name;\n    private int screen;\n    private String start_time;\n    private String stream;\n    private String thumb;\n    private String video;\n    private String app_shuffling_image;\n    private String categoryId;\n    private boolean hidden;\n    private boolean play_status;\n    private String icontext;\n    private String category_slug;\n    private String love_cover;\n\n    public LiveInfo(String no, String nick, String avatar, int follow, String id,\n                    String uid, String title, String category_id, String slug, String intro,\n                    String announcement, String cover, String play_at, String last_play_at,\n                    String view, String status, String priv, String landscape,\n                    String position, String weight, String check, String recommend_image,\n                    String videoQuality, String category_name, int screen,\n                    String start_time, String stream, String thumb, String video,\n                    String app_shuffling_image, String categoryId, boolean hidden,\n                    boolean play_status, String icontext, String category_slug, String love_cover) {\n        this.no = no;\n        this.nick = nick;\n        this.avatar = avatar;\n        this.follow = follow;\n        this.id = id;\n        this.uid = uid;\n        this.title = title;\n        this.category_id = category_id;\n        this.slug = slug;\n        this.intro = intro;\n        this.announcement = announcement;\n        this.cover = cover;\n        this.play_at = play_at;\n        this.last_play_at = last_play_at;\n        this.view = view;\n        this.status = status;\n        this.priv = priv;\n        this.landscape = landscape;\n        this.position = position;\n        this.weight = weight;\n        this.check = check;\n        this.recommend_image = recommend_image;\n        this.videoQuality = videoQuality;\n        this.category_name = category_name;\n        this.screen = screen;\n        this.start_time = start_time;\n        this.stream = stream;\n        this.thumb = thumb;\n        this.video = video;\n        this.app_shuffling_image = app_shuffling_image;\n        this.categoryId = categoryId;\n        this.hidden = hidden;\n        this.play_status = play_status;\n        this.icontext = icontext;\n        this.category_slug = category_slug;\n        this.love_cover = love_cover;\n    }\n\n    public LiveInfo() {\n    }\n\n    public String getNo() {\n        return no;\n    }\n\n    public void setNo(String no) {\n        this.no = no;\n    }\n\n    public String getNick() {\n        return nick;\n    }\n\n    public void setNick(String nick) {\n        this.nick = nick;\n    }\n\n    public String getAvatar() {\n        return avatar;\n    }\n\n    public void setAvatar(String avatar) {\n        this.avatar = avatar;\n    }\n\n    public int getFollow() {\n        return follow;\n    }\n\n    public void setFollow(int follow) {\n        this.follow = follow;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public void setId(String id) {\n        this.id = id;\n    }\n\n    public String getUid() {\n        return uid;\n    }\n\n    public void setUid(String uid) {\n        this.uid = uid;\n    }\n\n    public String getTitle() {\n        return title;\n    }\n\n    public void setTitle(String title) {\n        this.title = title;\n    }\n\n    public String getCategory_id() {\n        return category_id;\n    }\n\n    public void setCategory_id(String category_id) {\n        this.category_id = category_id;\n    }\n\n    public String getSlug() {\n        return slug;\n    }\n\n    public void setSlug(String slug) {\n        this.slug = slug;\n    }\n\n    public String getIntro() {\n        return intro;\n    }\n\n    public void setIntro(String intro) {\n        this.intro = intro;\n    }\n\n    public String getAnnouncement() {\n        return announcement;\n    }\n\n    public void setAnnouncement(String announcement) {\n        this.announcement = announcement;\n    }\n\n    public String getCover() {\n        return cover;\n    }\n\n    public void setCover(String cover) {\n        this.cover = cover;\n    }\n\n    public String getPlay_at() {\n        return play_at;\n    }\n\n    public void setPlay_at(String play_at) {\n        this.play_at = play_at;\n    }\n\n    public String getLast_play_at() {\n        return last_play_at;\n    }\n\n    public void setLast_play_at(String last_play_at) {\n        this.last_play_at = last_play_at;\n    }\n\n    public String getView() {\n        return view;\n    }\n\n    public void setView(String view) {\n        this.view = view;\n    }\n\n    public String getViews() {\n        try{\n            int views = Integer.parseInt(view);\n\n            return DecimalFormatUtil.formatW(views);\n        }catch (Exception e){\n\n        }\n\n        return view;\n    }\n\n\n    public String getStatus() {\n        return status;\n    }\n\n    public void setStatus(String status) {\n        this.status = status;\n    }\n\n    public String getPriv() {\n        return priv;\n    }\n\n    public void setPriv(String priv) {\n        this.priv = priv;\n    }\n\n    public String getLandscape() {\n        return landscape;\n    }\n\n    public void setLandscape(String landscape) {\n        this.landscape = landscape;\n    }\n\n    public String getPosition() {\n        return position;\n    }\n\n    public void setPosition(String position) {\n        this.position = position;\n    }\n\n    public String getWeight() {\n        return weight;\n    }\n\n    public void setWeight(String weight) {\n        this.weight = weight;\n    }\n\n    public String getCheck() {\n        return check;\n    }\n\n    public void setCheck(String check) {\n        this.check = check;\n    }\n\n    public String getRecommend_image() {\n        return recommend_image;\n    }\n\n    public void setRecommend_image(String recommend_image) {\n        this.recommend_image = recommend_image;\n    }\n\n    public String getVideoQuality() {\n        return videoQuality;\n    }\n\n    public void setVideoQuality(String videoQuality) {\n        this.videoQuality = videoQuality;\n    }\n\n    public String getCategory_name() {\n        return category_name;\n    }\n\n    public void setCategory_name(String category_name) {\n        this.category_name = category_name;\n    }\n\n    public int getScreen() {\n        return screen;\n    }\n\n    public void setScreen(int screen) {\n        this.screen = screen;\n    }\n\n    public String getStart_time() {\n        return start_time;\n    }\n\n    public void setStart_time(String start_time) {\n        this.start_time = start_time;\n    }\n\n    public String getStream() {\n        return stream;\n    }\n\n    public void setStream(String stream) {\n        this.stream = stream;\n    }\n\n    public String getThumb() {\n        return thumb;\n    }\n\n    public void setThumb(String thumb) {\n        this.thumb = thumb;\n    }\n\n    public String getVideo() {\n        return video;\n    }\n\n    public void setVideo(String video) {\n        this.video = video;\n    }\n\n    public String getApp_shuffling_image() {\n        return app_shuffling_image;\n    }\n\n    public void setApp_shuffling_image(String app_shuffling_image) {\n        this.app_shuffling_image = app_shuffling_image;\n    }\n\n    public String getCategoryId() {\n        return categoryId;\n    }\n\n    public void setCategoryId(String categoryId) {\n        this.categoryId = categoryId;\n    }\n\n    public boolean isHidden() {\n        return hidden;\n    }\n\n    public void setHidden(boolean hidden) {\n        this.hidden = hidden;\n    }\n\n    public boolean isPlay_status() {\n        return play_status;\n    }\n\n    public void setPlay_status(boolean play_status) {\n        this.play_status = play_status;\n    }\n\n    public String getIcontext() {\n        return icontext;\n    }\n\n    public void setIcontext(String icontext) {\n        this.icontext = icontext;\n    }\n\n    public String getCategory_slug() {\n        return category_slug;\n    }\n\n    public void setCategory_slug(String category_slug) {\n        this.category_slug = category_slug;\n    }\n\n    public boolean getHidden() {\n        return this.hidden;\n    }\n\n    public boolean getPlay_status() {\n        return this.play_status;\n    }\n\n    public String getLove_cover() {\n        return love_cover;\n    }\n\n    public void setLove_cover(String love_cover) {\n        this.love_cover = love_cover;\n    }\n\n    @Override\n    public String toString() {\n        return \"LiveInfo{\" +\n                \"no='\" + no + '\\'' +\n                \", nick='\" + nick + '\\'' +\n                \", avatar='\" + avatar + '\\'' +\n                \", follow=\" + follow +\n                \", id='\" + id + '\\'' +\n                \", uid='\" + uid + '\\'' +\n                \", title='\" + title + '\\'' +\n                \", category_id='\" + category_id + '\\'' +\n                \", slug='\" + slug + '\\'' +\n                \", intro='\" + intro + '\\'' +\n                \", announcement='\" + announcement + '\\'' +\n                \", cover='\" + cover + '\\'' +\n                \", play_at='\" + play_at + '\\'' +\n                \", last_play_at='\" + last_play_at + '\\'' +\n                \", view='\" + view + '\\'' +\n                \", status='\" + status + '\\'' +\n                \", priv='\" + priv + '\\'' +\n                \", landscape='\" + landscape + '\\'' +\n                \", position='\" + position + '\\'' +\n                \", weight='\" + weight + '\\'' +\n                \", check='\" + check + '\\'' +\n                \", recommend_image='\" + recommend_image + '\\'' +\n                \", videoQuality='\" + videoQuality + '\\'' +\n                \", category_name='\" + category_name + '\\'' +\n                \", screen=\" + screen +\n                \", start_time='\" + start_time + '\\'' +\n                \", stream='\" + stream + '\\'' +\n                \", thumb='\" + thumb + '\\'' +\n                \", video='\" + video + '\\'' +\n                \", app_shuffling_image='\" + app_shuffling_image + '\\'' +\n                \", categoryId='\" + categoryId + '\\'' +\n                \", hidden=\" + hidden +\n                \", play_status=\" + play_status +\n                \", icontext='\" + icontext + '\\'' +\n                \", category_slug='\" + category_slug + '\\'' +\n                \", love_cover='\" + love_cover + '\\'' +\n                '}';\n    }\n}\n"
  },
  {
    "path": "live/src/main/java/me/shouheng/live/model/data/Recommend.java",
    "content": "package me.shouheng.live.model.data;\n\nimport java.util.List;\n\nimport me.shouheng.live.common.DecimalFormatUtil;\n\npublic class Recommend {\n\n    /**\n     * id : 0\n     * name : 精彩推荐\n     * is_default : 1\n     * icon :\n     * slug :\n     * category_more :\n     * type : 1\n     * screen : 0\n     * list : [{\"beauty_cover\":\"\",\"no\":14800687,\"first_play_at\":\"1970-01-01 08:00:00\",\"category_name\":\"王者荣耀\",\"thumb\":\"http://snap.quanmin.tv/1509943928-1489628343-550.jpg?imageView2/2/w/390/\",\"last_play_at\":\"1970-01-01 08:00:00\",\"screen\":0,\"video\":\"http://thumb.quanmin.tv/1509943928.mp4?t=1489628100\",\"title\":\"我要回到铂金怀抱  不回铂金不睡觉\",\"recommend_image\":\"\",\"is_shield\":false,\"nick\":\"苏沫\",\"uid\":1509943928,\"view\":\"6058\",\"category_id\":17,\"stream\":\"http://flv.quanmin.tv/live/1509943928.flv\",\"slug\":\"sumo\",\"love_cover\":\"\",\"level\":0,\"like\":0,\"video_quality\":null,\"weight\":0,\"starlight\":10,\"check\":true,\"avatar\":\"http://a.img.shouyintv.cn/70Ok101-normal\",\"follow\":1522,\"play_count\":0,\"play_true\":0,\"fans\":0,\"max_view\":0,\"default_image\":\"\",\"last_end_at\":\"1970-01-01 08:00:00\",\"position\":\"外太空\",\"create_at\":\"2017-03-16 07:04:12\",\"last_thumb\":\"1509943928-1489583944-693.jpg\",\"landscape\":1,\"category_slug\":\"wangzhe\",\"anniversary\":0,\"play_status\":true,\"status\":2,\"coin\":10,\"link\":\"http://www.quanmin.tv/v/sumo\"},{\"beauty_cover\":\"\",\"no\":13544113,\"first_play_at\":\"1970-01-01 08:00:00\",\"category_name\":\"Showing\",\"thumb\":\"http://a.img.shouyintv.cn/1ZIo101-big\",\"last_play_at\":\"1970-01-01 08:00:00\",\"screen\":1,\"video\":\"http://thumb.quanmin.tv/1851753316.mp4?t=1489628100\",\"title\":\"秒变蓝孩纸\\u2026\\u2026\",\"recommend_image\":\"\",\"is_shield\":false,\"nick\":\"wuli瑶拉\",\"uid\":1851753316,\"view\":\"5182\",\"category_id\":29,\"stream\":\"http://flv.quanmin.tv/live/1851753316.flv\",\"slug\":null,\"love_cover\":\"http://a.img.shouyin.tv/YuAW101\",\"level\":0,\"like\":0,\"video_quality\":null,\"weight\":0,\"starlight\":206614,\"check\":true,\"avatar\":\"http://a.img.shouyintv.cn/1ZIo101-normal\",\"follow\":15789,\"play_count\":0,\"play_true\":0,\"fans\":0,\"max_view\":0,\"default_image\":\"\",\"last_end_at\":\"1970-01-01 08:00:00\",\"position\":\"外太空\",\"create_at\":\"2017-03-16 08:47:03\",\"last_thumb\":\"1851753316-1486704002-255.jpg\",\"landscape\":0,\"category_slug\":\"showing\",\"anniversary\":0,\"play_status\":true,\"status\":2,\"coin\":206614,\"link\":\"http://www.quanmin.tv/13544113\"},{\"beauty_cover\":\"\",\"no\":9007109,\"first_play_at\":\"1970-01-01 08:00:00\",\"category_name\":\"全民星秀\",\"thumb\":\"http://snap.quanmin.tv/9007109-1489628342-424.jpg?imageView2/2/w/390/\",\"last_play_at\":\"1970-01-01 08:00:00\",\"screen\":0,\"video\":\"http://thumb.quanmin.tv/9007109.mp4?t=1489628100\",\"title\":\"早上好这里是晨间欣欣\",\"recommend_image\":\"http://bj.bcebos.com/mas-service/14882605382602098d63be05e955da25526dc358a3ee7\",\"is_shield\":false,\"nick\":\"欣欣妹儿\",\"uid\":9007109,\"view\":\"9380\",\"category_id\":4,\"stream\":\"http://flv.quanmin.tv/live/9007109.flv\",\"slug\":\"\",\"love_cover\":\"http://image.quanmin.tv/love/30b824aea12577c64e9ee2379a6533bbjpg\",\"level\":0,\"like\":0,\"video_quality\":null,\"weight\":0,\"starlight\":520917,\"check\":true,\"avatar\":\"http://a.img.shouyintv.cn/cs3r101-normal\",\"follow\":19194,\"play_count\":0,\"play_true\":0,\"fans\":0,\"max_view\":0,\"default_image\":\"\",\"last_end_at\":\"1970-01-01 08:00:00\",\"position\":\"成都市\",\"app_shuffling_image\":\"http://bj.bcebos.com/mas-service/14882605512292098d63be05e955da25526dc358a3ee7\",\"create_at\":\"2017-03-16 08:34:22\",\"last_thumb\":\"9007109-1489582803-124.jpg\",\"landscape\":1,\"category_slug\":\"beauty\",\"anniversary\":0,\"play_status\":true,\"status\":2,\"coin\":520917,\"link\":\"http://www.quanmin.tv/9007109\"},{\"beauty_cover\":\"\",\"no\":13242623,\"first_play_at\":\"1970-01-01 08:00:00\",\"category_name\":\"守望先锋\",\"thumb\":\"http://snap.quanmin.tv/1784263034-1489628373-896.jpg?imageView2/2/w/390/\",\"last_play_at\":\"1970-01-01 08:00:00\",\"screen\":0,\"video\":\"http://thumb.quanmin.tv/1784263034.mp4?t=1489628100\",\"title\":\"又睡不着了，继续玩骚东西随缘上分\",\"recommend_image\":\"\",\"is_shield\":false,\"nick\":\"小天使六六酱\",\"uid\":1784263034,\"view\":\"5039\",\"category_id\":15,\"stream\":\"http://flv.quanmin.tv/live/1784263034_L3.flv\",\"slug\":null,\"love_cover\":\"\",\"level\":0,\"like\":0,\"video_quality\":null,\"weight\":0,\"starlight\":15306,\"check\":true,\"avatar\":\"http://a.img.shouyintv.cn/21zk101-normal\",\"follow\":1272,\"play_count\":0,\"play_true\":0,\"fans\":0,\"max_view\":0,\"default_image\":\"\",\"last_end_at\":\"1970-01-01 08:00:00\",\"position\":\"南京市\",\"create_at\":\"2017-03-16 06:39:13\",\"last_thumb\":\"1784263034-1489587819-34.jpg\",\"landscape\":1,\"category_slug\":\"overwatch\",\"anniversary\":0,\"play_status\":true,\"status\":2,\"coin\":15306,\"link\":\"http://www.quanmin.tv/13242623\"},{\"beauty_cover\":\"\",\"no\":806371,\"first_play_at\":\"1970-01-01 08:00:00\",\"category_name\":\"H1Z1\",\"thumb\":\"http://snap.quanmin.tv/806371-1489628343-291.jpg?imageView2/2/w/390/\",\"last_play_at\":\"1970-01-01 08:00:00\",\"screen\":0,\"video\":\"http://thumb.quanmin.tv/806371.mp4?t=1489628100\",\"title\":\"见面就是怼~~~~\",\"recommend_image\":\"\",\"is_shield\":false,\"nick\":\"玲儿么么哒\",\"uid\":806371,\"view\":\"2454\",\"category_id\":54,\"stream\":\"http://flv.quanmin.tv/live/806371.flv\",\"slug\":\"linger\",\"love_cover\":\"\",\"level\":0,\"like\":0,\"video_quality\":\"\",\"weight\":0,\"starlight\":4167,\"check\":true,\"avatar\":\"http://a.img.shouyintv.cn/sp0k101-normal\",\"follow\":4224,\"play_count\":0,\"play_true\":0,\"fans\":0,\"max_view\":0,\"default_image\":\"\",\"last_end_at\":\"1970-01-01 08:00:00\",\"position\":\"贺州市\",\"create_at\":\"2017-03-16 05:54:20\",\"last_thumb\":\"806371-1489560722-454.jpg\",\"landscape\":1,\"category_slug\":\"h1z1\",\"anniversary\":0,\"play_status\":true,\"status\":2,\"coin\":4167,\"link\":\"http://www.quanmin.tv/v/linger\"},{\"beauty_cover\":\"\",\"no\":5163677,\"first_play_at\":\"1970-01-01 08:00:00\",\"category_name\":\"全民户外\",\"thumb\":\"http://snap.quanmin.tv/3119090-1489628395-764.jpg?imageView2/2/w/390/\",\"last_play_at\":\"1970-01-01 08:00:00\",\"screen\":0,\"video\":\"http://thumb.quanmin.tv/3119090.mp4?t=1489628100\",\"title\":\"流浪生存第二十五天\",\"recommend_image\":\"\",\"is_shield\":false,\"nick\":\"陈朋朋\",\"uid\":3119090,\"view\":\"4360\",\"category_id\":13,\"stream\":\"http://flv.quanmin.tv/live/3119090.flv\",\"slug\":null,\"love_cover\":\"\",\"level\":0,\"like\":0,\"video_quality\":null,\"weight\":0,\"starlight\":176,\"check\":true,\"avatar\":\"http://a.img.shouyintv.cn/jBKq101-normal\",\"follow\":204,\"play_count\":0,\"play_true\":0,\"fans\":0,\"max_view\":0,\"default_image\":\"\",\"last_end_at\":\"1970-01-01 08:00:00\",\"position\":\"外太空\",\"create_at\":\"2017-03-16 08:53:49\",\"last_thumb\":\"3119090-1489543931-117.jpg\",\"landscape\":1,\"category_slug\":\"huwai\",\"anniversary\":0,\"play_status\":true,\"status\":2,\"coin\":176,\"link\":\"http://www.quanmin.tv/5163677\"}]\n     */\n\n    private List<RoomBean> room;\n    private List<?> ad;\n\n    public List<RoomBean> getRoom() {\n        return room;\n    }\n\n    public void setRoom(List<RoomBean> room) {\n        this.room = room;\n    }\n\n    public List<?> getAd() {\n        return ad;\n    }\n\n    public void setAd(List<?> ad) {\n        this.ad = ad;\n    }\n\n    public static class RoomBean {\n        private int id;\n        private String name;\n        private int is_default;\n        private String icon;\n        private String slug;\n        private String category_more;\n        private int type;\n        private int screen;\n        /**\n         * beauty_cover :\n         * no : 14800687\n         * first_play_at : 1970-01-01 08:00:00\n         * category_name : 王者荣耀\n         * thumb : http://snap.quanmin.tv/1509943928-1489628343-550.jpg?imageView2/2/w/390/\n         * last_play_at : 1970-01-01 08:00:00\n         * screen : 0\n         * video : http://thumb.quanmin.tv/1509943928.mp4?t=1489628100\n         * title : 我要回到铂金怀抱  不回铂金不睡觉\n         * recommend_image :\n         * is_shield : false\n         * nick : 苏沫\n         * uid : 1509943928\n         * view : 6058\n         * category_id : 17\n         * stream : http://flv.quanmin.tv/live/1509943928.flv\n         * slug : sumo\n         * love_cover :\n         * level : 0\n         * like : 0\n         * video_quality : null\n         * weight : 0\n         * starlight : 10\n         * check : true\n         * avatar : http://a.img.shouyintv.cn/70Ok101-normal\n         * follow : 1522\n         * play_count : 0\n         * play_true : 0\n         * fans : 0\n         * max_view : 0\n         * default_image :\n         * last_end_at : 1970-01-01 08:00:00\n         * position : 外太空\n         * create_at : 2017-03-16 07:04:12\n         * last_thumb : 1509943928-1489583944-693.jpg\n         * landscape : 1\n         * category_slug : wangzhe\n         * anniversary : 0\n         * play_status : true\n         * status : 2\n         * coin : 10\n         * link : http://www.quanmin.tv/v/sumo\n         */\n\n        private List<ListBean> list;\n\n        public int getId() {\n            return id;\n        }\n\n        public void setId(int id) {\n            this.id = id;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        public int getIs_default() {\n            return is_default;\n        }\n\n        public void setIs_default(int is_default) {\n            this.is_default = is_default;\n        }\n\n        public String getIcon() {\n            return icon;\n        }\n\n        public void setIcon(String icon) {\n            this.icon = icon;\n        }\n\n        public String getSlug() {\n            return slug;\n        }\n\n        public void setSlug(String slug) {\n            this.slug = slug;\n        }\n\n        public String getCategory_more() {\n            return category_more;\n        }\n\n        public void setCategory_more(String category_more) {\n            this.category_more = category_more;\n        }\n\n        public int getType() {\n            return type;\n        }\n\n        public void setType(int type) {\n            this.type = type;\n        }\n\n        public int getScreen() {\n            return screen;\n        }\n\n        public void setScreen(int screen) {\n            this.screen = screen;\n        }\n\n        public List<ListBean> getList() {\n            return list;\n        }\n\n        public void setList(List<ListBean> list) {\n            this.list = list;\n        }\n\n        public static class ListBean {\n            private String beauty_cover;\n            private int no;\n            private String first_play_at;\n            private String category_name;\n            private String thumb;\n            private String last_play_at;\n            private int screen;\n            private String video;\n            private String title;\n            private String recommend_image;\n            private boolean is_shield;\n            private String nick;\n            private int uid;\n            private String view;\n            private int category_id;\n            private String stream;\n            private String slug;\n            private String love_cover;\n            private int level;\n            private int like;\n            private Object video_quality;\n            private int weight;\n            private int starlight;\n            private boolean check;\n            private String avatar;\n            private int follow;\n            private int play_count;\n            private int play_true;\n            private int fans;\n            private int max_view;\n            private String default_image;\n            private String last_end_at;\n            private String position;\n            private String create_at;\n            private String last_thumb;\n            private int landscape;\n            private String category_slug;\n            private int anniversary;\n            private boolean play_status;\n            private int status;\n            private int coin;\n            private String link;\n\n            public String getBeauty_cover() {\n                return beauty_cover;\n            }\n\n            public void setBeauty_cover(String beauty_cover) {\n                this.beauty_cover = beauty_cover;\n            }\n\n            public int getNo() {\n                return no;\n            }\n\n            public void setNo(int no) {\n                this.no = no;\n            }\n\n            public String getFirst_play_at() {\n                return first_play_at;\n            }\n\n            public void setFirst_play_at(String first_play_at) {\n                this.first_play_at = first_play_at;\n            }\n\n            public String getCategory_name() {\n                return category_name;\n            }\n\n            public void setCategory_name(String category_name) {\n                this.category_name = category_name;\n            }\n\n            public String getThumb() {\n                return thumb;\n            }\n\n            public void setThumb(String thumb) {\n                this.thumb = thumb;\n            }\n\n            public String getLast_play_at() {\n                return last_play_at;\n            }\n\n            public void setLast_play_at(String last_play_at) {\n                this.last_play_at = last_play_at;\n            }\n\n            public int getScreen() {\n                return screen;\n            }\n\n            public void setScreen(int screen) {\n                this.screen = screen;\n            }\n\n            public String getVideo() {\n                return video;\n            }\n\n            public void setVideo(String video) {\n                this.video = video;\n            }\n\n            public String getTitle() {\n                return title;\n            }\n\n            public void setTitle(String title) {\n                this.title = title;\n            }\n\n            public String getRecommend_image() {\n                return recommend_image;\n            }\n\n            public void setRecommend_image(String recommend_image) {\n                this.recommend_image = recommend_image;\n            }\n\n            public boolean isIs_shield() {\n                return is_shield;\n            }\n\n            public void setIs_shield(boolean is_shield) {\n                this.is_shield = is_shield;\n            }\n\n            public String getNick() {\n                return nick;\n            }\n\n            public void setNick(String nick) {\n                this.nick = nick;\n            }\n\n            public int getUid() {\n                return uid;\n            }\n\n            public void setUid(int uid) {\n                this.uid = uid;\n            }\n\n            public String getView() {\n                return view;\n            }\n\n\n            public String getViews() {\n                try{\n                    int views = Integer.parseInt(view);\n\n                    return DecimalFormatUtil.formatW(views);\n                }catch (Exception e){\n\n                }\n\n                return view;\n            }\n\n            public void setView(String view) {\n                this.view = view;\n            }\n\n            public int getCategory_id() {\n                return category_id;\n            }\n\n            public void setCategory_id(int category_id) {\n                this.category_id = category_id;\n            }\n\n            public String getStream() {\n                return stream;\n            }\n\n            public void setStream(String stream) {\n                this.stream = stream;\n            }\n\n            public String getSlug() {\n                return slug;\n            }\n\n            public void setSlug(String slug) {\n                this.slug = slug;\n            }\n\n            public String getLove_cover() {\n                return love_cover;\n            }\n\n            public void setLove_cover(String love_cover) {\n                this.love_cover = love_cover;\n            }\n\n            public int getLevel() {\n                return level;\n            }\n\n            public void setLevel(int level) {\n                this.level = level;\n            }\n\n            public int getLike() {\n                return like;\n            }\n\n            public void setLike(int like) {\n                this.like = like;\n            }\n\n            public Object getVideo_quality() {\n                return video_quality;\n            }\n\n            public void setVideo_quality(Object video_quality) {\n                this.video_quality = video_quality;\n            }\n\n            public int getWeight() {\n                return weight;\n            }\n\n            public void setWeight(int weight) {\n                this.weight = weight;\n            }\n\n            public int getStarlight() {\n                return starlight;\n            }\n\n            public void setStarlight(int starlight) {\n                this.starlight = starlight;\n            }\n\n            public boolean isCheck() {\n                return check;\n            }\n\n            public void setCheck(boolean check) {\n                this.check = check;\n            }\n\n            public String getAvatar() {\n                return avatar;\n            }\n\n            public void setAvatar(String avatar) {\n                this.avatar = avatar;\n            }\n\n            public int getFollow() {\n                return follow;\n            }\n\n            public void setFollow(int follow) {\n                this.follow = follow;\n            }\n\n            public int getPlay_count() {\n                return play_count;\n            }\n\n            public void setPlay_count(int play_count) {\n                this.play_count = play_count;\n            }\n\n            public int getPlay_true() {\n                return play_true;\n            }\n\n            public void setPlay_true(int play_true) {\n                this.play_true = play_true;\n            }\n\n            public int getFans() {\n                return fans;\n            }\n\n            public void setFans(int fans) {\n                this.fans = fans;\n            }\n\n            public int getMax_view() {\n                return max_view;\n            }\n\n            public void setMax_view(int max_view) {\n                this.max_view = max_view;\n            }\n\n            public String getDefault_image() {\n                return default_image;\n            }\n\n            public void setDefault_image(String default_image) {\n                this.default_image = default_image;\n            }\n\n            public String getLast_end_at() {\n                return last_end_at;\n            }\n\n            public void setLast_end_at(String last_end_at) {\n                this.last_end_at = last_end_at;\n            }\n\n            public String getPosition() {\n                return position;\n            }\n\n            public void setPosition(String position) {\n                this.position = position;\n            }\n\n            public String getCreate_at() {\n                return create_at;\n            }\n\n            public void setCreate_at(String create_at) {\n                this.create_at = create_at;\n            }\n\n            public String getLast_thumb() {\n                return last_thumb;\n            }\n\n            public void setLast_thumb(String last_thumb) {\n                this.last_thumb = last_thumb;\n            }\n\n            public int getLandscape() {\n                return landscape;\n            }\n\n            public void setLandscape(int landscape) {\n                this.landscape = landscape;\n            }\n\n            public String getCategory_slug() {\n                return category_slug;\n            }\n\n            public void setCategory_slug(String category_slug) {\n                this.category_slug = category_slug;\n            }\n\n            public int getAnniversary() {\n                return anniversary;\n            }\n\n            public void setAnniversary(int anniversary) {\n                this.anniversary = anniversary;\n            }\n\n            public boolean isPlay_status() {\n                return play_status;\n            }\n\n            public void setPlay_status(boolean play_status) {\n                this.play_status = play_status;\n            }\n\n            public int getStatus() {\n                return status;\n            }\n\n            public void setStatus(int status) {\n                this.status = status;\n            }\n\n            public int getCoin() {\n                return coin;\n            }\n\n            public void setCoin(int coin) {\n                this.coin = coin;\n            }\n\n            public String getLink() {\n                return link;\n            }\n\n            public void setLink(String link) {\n                this.link = link;\n            }\n        }\n\n        @Override\n        public String toString() {\n            return \"RoomBean{\" +\n                    \"id=\" + id +\n                    \", name='\" + name + '\\'' +\n                    \", is_default=\" + is_default +\n                    \", icon='\" + icon + '\\'' +\n                    \", slug='\" + slug + '\\'' +\n                    \", category_more='\" + category_more + '\\'' +\n                    \", type=\" + type +\n                    \", screen=\" + screen +\n                    \", list=\" + list +\n                    '}';\n        }\n    }\n\n    @Override\n    public String toString() {\n        return \"Recommend{\" +\n                \"room=\" + room +\n                \", ad=\" + ad +\n                '}';\n    }\n}\n"
  },
  {
    "path": "live/src/main/java/me/shouheng/live/model/data/Room.java",
    "content": "package me.shouheng.live.model.data;\n\nimport java.util.List;\n\npublic class Room {\n\n\n    /**\n     * uid : 326745\n     * no : 326745\n     * title : 国服第一诺克，1打9阿。\n     * nick : 浏阳河长的像猴子\n     * avatar : http://image.quanmin.tv/avatar/ad569547dfe896f22a7bc5b1d4ecd3d5gif?imageView2/2/w/300/\n     * slug : qq312118607\n     * intro : 保持善良 宽容，不忘初心。\n     * category_id : 1\n     * category_name : 英雄联盟\n     * screen : 0\n     * view : 28\n     * weight : 103820720\n     * follow : 268146\n     * last_play_at :\n     * announcement : 直播时间，上午9点到下午3点。\n     * play_at : 2017-03-07 09:59:17\n     * thumb : http://snap.quanmin.tv/326745-1488874623-878.jpg?imageView2/2/w/390/\n     * status : 0\n     * play_status : false\n     * forbid_status : false\n     * police_forbid : false\n     * admins : []\n     * notice : []\n     * hidden : false\n     * video_quality : 234\n     * room_lines : [{\"name\":\"tx\",\"flv\":{\"3\":{\"name\":\"标清\",\"src\":\"http://flv3.quanmin.tv/live/3766_326745_550.flv\"},\"4\":{\"name\":\"高清\",\"src\":\"http://flv3.quanmin.tv/live/3766_326745_900.flv\"},\"5\":{\"name\":\"超清\",\"src\":\"http://flv3.quanmin.tv/live/3766_326745.flv\"},\"main_mobile\":3,\"main_pc\":4},\"hls\":{\"3\":{\"name\":\"标清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745_550.m3u8\"},\"4\":{\"name\":\"高清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745_900.m3u8\"},\"5\":{\"name\":\"超清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745.m3u8\"},\"main_mobile\":3,\"main_pc\":4},\"def_mobile\":\"flv\",\"def_pc\":\"flv\",\"v\":\"1\"},{\"name\":\"ws\",\"flv\":{\"3\":{\"name\":\"标清\",\"src\":\"http://flv.quanmin.tv/live/326745_L3.flv\"},\"4\":{\"name\":\"高清\",\"src\":\"http://flv.quanmin.tv/live/326745_L4.flv\"},\"5\":{\"name\":\"超清\",\"src\":\"http://flv.quanmin.tv/live/326745.flv\"},\"main_mobile\":3,\"main_pc\":4},\"hls\":{\"3\":{\"name\":\"标清\",\"src\":\"http://hls.quanmin.tv/live/326745_L3/playlist.m3u8\"},\"4\":{\"name\":\"高清\",\"src\":\"http://hls.quanmin.tv/live/326745_L4/playlist.m3u8\"},\"5\":{\"name\":\"超清\",\"src\":\"http://hls.quanmin.tv/live/326745/playlist.m3u8\"},\"main_mobile\":3,\"main_pc\":4},\"def_mobile\":\"flv\",\"def_pc\":\"flv\",\"v\":\"1\"},{\"name\":\"bd\",\"flv\":{\"3\":{\"name\":\"标清\",\"src\":\"http://flv2.quanmin.tv/live/326745-L3.flv\"},\"4\":{\"name\":\"高清\",\"src\":\"http://flv2.quanmin.tv/live/326745-L4.flv\"},\"5\":{\"name\":\"超清\",\"src\":\"http://flv2.quanmin.tv/live/326745.flv\"},\"main_mobile\":3,\"main_pc\":4},\"hls\":{\"3\":{\"name\":\"标清\",\"src\":\"http://hls2.quanmin.tv/live/326745-L3.m3u8\"},\"4\":{\"name\":\"高清\",\"src\":\"http://hls2.quanmin.tv/live/326745-L4.m3u8\"},\"5\":{\"name\":\"超清\",\"src\":\"http://hls2.quanmin.tv/live/326745.m3u8\"},\"main_mobile\":3,\"main_pc\":4},\"def_mobile\":\"flv\",\"def_pc\":\"flv\",\"v\":\"1\"},{\"name\":\"ali\",\"flv\":{\"3\":{\"name\":\"标清\",\"src\":\"http://liveal.quanmin.tv/live/326745_quanmin576.flv\"},\"4\":{\"name\":\"高清\",\"src\":\"http://liveal.quanmin.tv/live/326745_quanmin720.flv\"},\"5\":{\"name\":\"超清\",\"src\":\"http://liveal.quanmin.tv/live/326745.flv\"},\"main_mobile\":3,\"main_pc\":4},\"hls\":{\"3\":{\"name\":\"标清\",\"src\":\"http://liveal.quanmin.tv/live/326745_quanmin576.m3u8\"},\"4\":{\"name\":\"高清\",\"src\":\"http://liveal.quanmin.tv/live/326745_quanmin720.m3u8\"},\"5\":{\"name\":\"超清\",\"src\":\"http://liveal.quanmin.tv/live/326745.m3u8\"},\"main_mobile\":3,\"main_pc\":4},\"def_mobile\":\"flv\",\"def_pc\":\"flv\",\"v\":\"1\"},{\"name\":\"qn\",\"flv\":{\"3\":{\"name\":\"标清\",\"src\":\"http://flv5.quanmin.tv/live/326745@quanmin_sd_720p.flv\"},\"4\":{\"name\":\"高清\",\"src\":\"http://flv5.quanmin.tv/live/326745@quanmin_hd_720p.flv\"},\"5\":{\"name\":\"超清\",\"src\":\"http://flv5.quanmin.tv/live/326745.flv\"},\"main_mobile\":3,\"main_pc\":4},\"hls\":{\"3\":{\"name\":\"标清\",\"src\":\"http://flv5.quanmin.tv/live/326745@quanmin_sd_720p.m3u8\"},\"4\":{\"name\":\"高清\",\"src\":\"http://flv5.quanmin.tv/live/326745@quanmin_hd_720p.m3u8\"},\"5\":{\"name\":\"超清\",\"src\":\"http://flv5.quanmin.tv/live/326745.m3u8\"},\"main_mobile\":3,\"main_pc\":4},\"def_mobile\":\"flv\",\"def_pc\":\"flv\",\"v\":\"1\"}]\n     * live : {\"ws\":{\"name\":\"tx\",\"flv\":{\"3\":{\"name\":\"标清\",\"src\":\"http://flv3.quanmin.tv/live/3766_326745_550.flv\"},\"4\":{\"name\":\"高清\",\"src\":\"http://flv3.quanmin.tv/live/3766_326745_900.flv\"},\"5\":{\"name\":\"超清\",\"src\":\"http://flv3.quanmin.tv/live/3766_326745.flv\"},\"main_mobile\":3,\"main_pc\":4},\"hls\":{\"3\":{\"name\":\"标清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745_550.m3u8\"},\"4\":{\"name\":\"高清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745_900.m3u8\"},\"5\":{\"name\":\"超清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745.m3u8\"},\"main_mobile\":3,\"main_pc\":4},\"def_mobile\":\"flv\",\"def_pc\":\"flv\",\"v\":\"1\"}}\n     * is_star : false\n     * special : null\n     * hot_word : [\"吃我一记霸天斩(╰_╯)\",\"王八之气\",\"帅不过三秒\",\"二营长，老子的意大利炮呢！\",\"琳琳超人 救命啊~\",\"因吹思婷\",\"帅男，自己人\",\"666666666\"]\n     * watermark : 1\n     * watermark_pic :\n     * rank_week : []\n     * rank_total : []\n     * rank_curr : [{\"send_uid\":\"326745\",\"send_nick\":\"朗天义\",\"avatar\":\"http://a.img.shouyintv.cn/dg5l102-normal\",\"rank\":11,\"score\":1011,\"icon\":\"/static/images/lv/11.png?v=2\"},{\"send_uid\":\"326745\",\"send_nick\":\"RAYMK\",\"avatar\":\"http://a.img.shouyintv.cn/hkgg101-normal\",\"rank\":7,\"score\":60,\"icon\":\"/static/images/lv/7.png?v=2\"},{\"send_uid\":\"326745\",\"send_nick\":\"日本加微KAV0\",\"avatar\":\"http://a.img.shouyintv.cn/default-normal\",\"rank\":1,\"score\":26,\"icon\":\"/static/images/lv/1.png?v=2\"},{\"send_uid\":\"326745\",\"send_nick\":\"飞翔\",\"avatar\":\"http://a.img.shouyintv.cn/IFYo101-normal\",\"rank\":1,\"score\":24,\"icon\":\"/static/images/lv/1.png?v=2\"},{\"send_uid\":\"326745\",\"send_nick\":\"XD铭\",\"avatar\":\"http://image.quanmin.tv/avatar/b85dfde18b6840989b1dc00faf39fecejpg?imageView2/2/w/300/\",\"rank\":1,\"score\":10,\"icon\":\"/static/images/lv/1.png?v=2\"},{\"send_uid\":\"326745\",\"send_nick\":\"全民tv冷小莫\",\"avatar\":\"http://a.img.shouyintv.cn/JE8e101-normal\",\"rank\":1,\"score\":10,\"icon\":\"/static/images/lv/1.png?v=2\"},{\"send_uid\":\"326745\",\"send_nick\":\"敢为天下先\",\"avatar\":\"http://a.img.shouyintv.cn/F59n101-normal\",\"rank\":1,\"score\":4,\"icon\":\"/static/images/lv/1.png?v=2\"},{\"send_uid\":\"326745\",\"send_nick\":\"智巴巴丶呵呵哒\",\"avatar\":\"http://image.quanmin.tv/avatar/a4b88f2f7b3ab1ecf44e10c3f4f4c1ecpng?imageView2/2/w/300/\",\"rank\":5,\"score\":4,\"icon\":\"/static/images/lv/5.png?v=2\"}]\n     * girl_rank : {\"curAnchorInfo\":{\"avatar\":\"http://image.quanmin.tv/avatar/ad569547dfe896f22a7bc5b1d4ecd3d5gif?imageView2/2/w/300/\",\"nick\":\"浏阳河长的像猴子\",\"uid\":326745,\"no\":326745,\"votes\":2430,\"rank\":43,\"toPre\":0,\"rankType\":\"GAME\"},\"rank\":[{\"avatar\":\"http://image.quanmin.tv/avatar/4929b40c878e3b572c1eefb27dc06e48png?imageView2/2/w/300/\",\"nick\":\"全民小龙\",\"uid\":29105,\"votes\":64860,\"no\":29105,\"status\":0},{\"avatar\":\"http://image.quanmin.tv/avatar/70a37ce87dafaf0bec7628fd5d6a0c62?imageView2/2/w/300/\",\"nick\":\"阿怡丶全民\",\"uid\":8832533,\"votes\":34960,\"no\":8832533,\"status\":0},{\"avatar\":\"http://a.img.shouyintv.cn/RFOk101-normal\",\"nick\":\"顾正文\",\"uid\":1847517564,\"votes\":32690,\"no\":688888,\"status\":0},{\"avatar\":\"http://image.quanmin.tv/avatar/753be4b6ff7b6c7a0e8814e0c7d50a30jpg?imageView2/2/w/300/\",\"nick\":\"全民八路奶粉\",\"uid\":1688553,\"votes\":30950,\"no\":1688553,\"status\":0},{\"avatar\":\"http://image.quanmin.tv/avatar/8ed7ac3fcd4cd8aecb31d07af42211f3jpg?imageView2/2/w/300/\",\"nick\":\"全民丶蜘蛛馍\",\"uid\":4025818,\"votes\":27580,\"no\":4025818,\"status\":2},{\"avatar\":\"http://image.quanmin.tv/avatar/af82e8857199af61532dea7274033667?imageView2/2/w/300/\",\"nick\":\"聪全蛋\",\"uid\":3446603,\"votes\":17730,\"no\":3446603,\"status\":0},{\"avatar\":\"http://a.img.shouyintv.cn/FX3Y101-normal\",\"nick\":\"梦月\",\"uid\":45644,\"votes\":17440,\"no\":45644,\"status\":0},{\"avatar\":\"http://image.quanmin.tv/avatar/e45f22bf5fbc02f272b1be9de6ed73a6jpg?imageView2/2/w/300/\",\"nick\":\"全民TV蓝猫\",\"uid\":42416,\"votes\":15600,\"no\":42416,\"status\":0},{\"avatar\":\"http://a.img.shouyintv.cn/qoym101-normal\",\"nick\":\"全民TV丶H猫\",\"uid\":3475,\"votes\":14120,\"no\":3475,\"status\":0},{\"avatar\":\"http://image.quanmin.tv/avatar/269782ed0cd2344143bab25fa9b22749?imageView2/2/w/300/\",\"nick\":\"徐老师LIVE\",\"uid\":911,\"votes\":13530,\"no\":911,\"status\":0}]}\n     */\n\n    private int uid;\n    private int no;\n    private String title;\n    private String nick;\n    private String avatar;\n    private String slug;\n    private String intro;\n    private String category_id;\n    private String category_name;\n    private int screen;\n    private int view;\n    private int weight;\n    private int follow;\n    private String last_play_at;\n    private String announcement;\n    private String play_at;\n    private String thumb;\n    private String status;\n    private boolean play_status;\n    private boolean forbid_status;\n    private boolean police_forbid;\n    private boolean hidden;\n    private String video_quality;\n    /**\n     * ws : {\"name\":\"tx\",\"flv\":{\"3\":{\"name\":\"标清\",\"src\":\"http://flv3.quanmin.tv/live/3766_326745_550.flv\"},\"4\":{\"name\":\"高清\",\"src\":\"http://flv3.quanmin.tv/live/3766_326745_900.flv\"},\"5\":{\"name\":\"超清\",\"src\":\"http://flv3.quanmin.tv/live/3766_326745.flv\"},\"main_mobile\":3,\"main_pc\":4},\"hls\":{\"3\":{\"name\":\"标清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745_550.m3u8\"},\"4\":{\"name\":\"高清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745_900.m3u8\"},\"5\":{\"name\":\"超清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745.m3u8\"},\"main_mobile\":3,\"main_pc\":4},\"def_mobile\":\"flv\",\"def_pc\":\"flv\",\"v\":\"1\"}\n     */\n\n    private LiveBean live;\n    private boolean is_star;\n    private Object special;\n    private int watermark;\n    private String watermark_pic;\n    /**\n     * curAnchorInfo : {\"avatar\":\"http://image.quanmin.tv/avatar/ad569547dfe896f22a7bc5b1d4ecd3d5gif?imageView2/2/w/300/\",\"nick\":\"浏阳河长的像猴子\",\"uid\":326745,\"no\":326745,\"votes\":2430,\"rank\":43,\"toPre\":0,\"rankType\":\"GAME\"}\n     * rank : [{\"avatar\":\"http://image.quanmin.tv/avatar/4929b40c878e3b572c1eefb27dc06e48png?imageView2/2/w/300/\",\"nick\":\"全民小龙\",\"uid\":29105,\"votes\":64860,\"no\":29105,\"status\":0},{\"avatar\":\"http://image.quanmin.tv/avatar/70a37ce87dafaf0bec7628fd5d6a0c62?imageView2/2/w/300/\",\"nick\":\"阿怡丶全民\",\"uid\":8832533,\"votes\":34960,\"no\":8832533,\"status\":0},{\"avatar\":\"http://a.img.shouyintv.cn/RFOk101-normal\",\"nick\":\"顾正文\",\"uid\":1847517564,\"votes\":32690,\"no\":688888,\"status\":0},{\"avatar\":\"http://image.quanmin.tv/avatar/753be4b6ff7b6c7a0e8814e0c7d50a30jpg?imageView2/2/w/300/\",\"nick\":\"全民八路奶粉\",\"uid\":1688553,\"votes\":30950,\"no\":1688553,\"status\":0},{\"avatar\":\"http://image.quanmin.tv/avatar/8ed7ac3fcd4cd8aecb31d07af42211f3jpg?imageView2/2/w/300/\",\"nick\":\"全民丶蜘蛛馍\",\"uid\":4025818,\"votes\":27580,\"no\":4025818,\"status\":2},{\"avatar\":\"http://image.quanmin.tv/avatar/af82e8857199af61532dea7274033667?imageView2/2/w/300/\",\"nick\":\"聪全蛋\",\"uid\":3446603,\"votes\":17730,\"no\":3446603,\"status\":0},{\"avatar\":\"http://a.img.shouyintv.cn/FX3Y101-normal\",\"nick\":\"梦月\",\"uid\":45644,\"votes\":17440,\"no\":45644,\"status\":0},{\"avatar\":\"http://image.quanmin.tv/avatar/e45f22bf5fbc02f272b1be9de6ed73a6jpg?imageView2/2/w/300/\",\"nick\":\"全民TV蓝猫\",\"uid\":42416,\"votes\":15600,\"no\":42416,\"status\":0},{\"avatar\":\"http://a.img.shouyintv.cn/qoym101-normal\",\"nick\":\"全民TV丶H猫\",\"uid\":3475,\"votes\":14120,\"no\":3475,\"status\":0},{\"avatar\":\"http://image.quanmin.tv/avatar/269782ed0cd2344143bab25fa9b22749?imageView2/2/w/300/\",\"nick\":\"徐老师LIVE\",\"uid\":911,\"votes\":13530,\"no\":911,\"status\":0}]\n     */\n\n    private GirlRankBean girl_rank;\n    private List<?> admins;\n    private List<?> notice;\n    /**\n     * name : tx\n     * flv : {\"3\":{\"name\":\"标清\",\"src\":\"http://flv3.quanmin.tv/live/3766_326745_550.flv\"},\"4\":{\"name\":\"高清\",\"src\":\"http://flv3.quanmin.tv/live/3766_326745_900.flv\"},\"5\":{\"name\":\"超清\",\"src\":\"http://flv3.quanmin.tv/live/3766_326745.flv\"},\"main_mobile\":3,\"main_pc\":4}\n     * hls : {\"3\":{\"name\":\"标清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745_550.m3u8\"},\"4\":{\"name\":\"高清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745_900.m3u8\"},\"5\":{\"name\":\"超清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745.m3u8\"},\"main_mobile\":3,\"main_pc\":4}\n     * def_mobile : flv\n     * def_pc : flv\n     * v : 1\n     */\n\n    private List<RoomLine> room_lines;\n    private List<String> hot_word;\n    private List<?> rank_week;\n    private List<?> rank_total;\n    /**\n     * send_uid : 326745\n     * send_nick : 朗天义\n     * avatar : http://a.img.shouyintv.cn/dg5l102-normal\n     * rank : 11\n     * score : 1011\n     * icon : /static/images/lv/11.png?v=2\n     */\n\n    private List<RankCurrBean> rank_curr;\n\n    public int getUid() {\n        return uid;\n    }\n\n    public void setUid(int uid) {\n        this.uid = uid;\n    }\n\n    public int getNo() {\n        return no;\n    }\n\n    public void setNo(int no) {\n        this.no = no;\n    }\n\n    public String getTitle() {\n        return title;\n    }\n\n    public void setTitle(String title) {\n        this.title = title;\n    }\n\n    public String getNick() {\n        return nick;\n    }\n\n    public void setNick(String nick) {\n        this.nick = nick;\n    }\n\n    public String getAvatar() {\n        return avatar;\n    }\n\n    public void setAvatar(String avatar) {\n        this.avatar = avatar;\n    }\n\n    public String getSlug() {\n        return slug;\n    }\n\n    public void setSlug(String slug) {\n        this.slug = slug;\n    }\n\n    public String getIntro() {\n        return intro;\n    }\n\n    public void setIntro(String intro) {\n        this.intro = intro;\n    }\n\n    public String getCategory_id() {\n        return category_id;\n    }\n\n    public void setCategory_id(String category_id) {\n        this.category_id = category_id;\n    }\n\n    public String getCategory_name() {\n        return category_name;\n    }\n\n    public void setCategory_name(String category_name) {\n        this.category_name = category_name;\n    }\n\n    public int getScreen() {\n        return screen;\n    }\n\n    public void setScreen(int screen) {\n        this.screen = screen;\n    }\n\n    public int getView() {\n        return view;\n    }\n\n    public void setView(int view) {\n        this.view = view;\n    }\n\n    public int getWeight() {\n        return weight;\n    }\n\n    public void setWeight(int weight) {\n        this.weight = weight;\n    }\n\n    public int getFollow() {\n        return follow;\n    }\n\n    public void setFollow(int follow) {\n        this.follow = follow;\n    }\n\n    public String getLast_play_at() {\n        return last_play_at;\n    }\n\n    public void setLast_play_at(String last_play_at) {\n        this.last_play_at = last_play_at;\n    }\n\n    public String getAnnouncement() {\n        return announcement;\n    }\n\n    public void setAnnouncement(String announcement) {\n        this.announcement = announcement;\n    }\n\n    public String getPlay_at() {\n        return play_at;\n    }\n\n    public void setPlay_at(String play_at) {\n        this.play_at = play_at;\n    }\n\n    public String getThumb() {\n        return thumb;\n    }\n\n    public void setThumb(String thumb) {\n        this.thumb = thumb;\n    }\n\n    public String getStatus() {\n        return status;\n    }\n\n    public void setStatus(String status) {\n        this.status = status;\n    }\n\n    public boolean isPlay_status() {\n        return play_status;\n    }\n\n    public void setPlay_status(boolean play_status) {\n        this.play_status = play_status;\n    }\n\n    public boolean isForbid_status() {\n        return forbid_status;\n    }\n\n    public void setForbid_status(boolean forbid_status) {\n        this.forbid_status = forbid_status;\n    }\n\n    public boolean isPolice_forbid() {\n        return police_forbid;\n    }\n\n    public void setPolice_forbid(boolean police_forbid) {\n        this.police_forbid = police_forbid;\n    }\n\n    public boolean isHidden() {\n        return hidden;\n    }\n\n    public void setHidden(boolean hidden) {\n        this.hidden = hidden;\n    }\n\n    public String getVideo_quality() {\n        return video_quality;\n    }\n\n    public void setVideo_quality(String video_quality) {\n        this.video_quality = video_quality;\n    }\n\n    public LiveBean getLive() {\n        return live;\n    }\n\n    public void setLive(LiveBean live) {\n        this.live = live;\n    }\n\n    public boolean isIs_star() {\n        return is_star;\n    }\n\n    public void setIs_star(boolean is_star) {\n        this.is_star = is_star;\n    }\n\n    public Object getSpecial() {\n        return special;\n    }\n\n    public void setSpecial(Object special) {\n        this.special = special;\n    }\n\n    public int getWatermark() {\n        return watermark;\n    }\n\n    public void setWatermark(int watermark) {\n        this.watermark = watermark;\n    }\n\n    public String getWatermark_pic() {\n        return watermark_pic;\n    }\n\n    public void setWatermark_pic(String watermark_pic) {\n        this.watermark_pic = watermark_pic;\n    }\n\n    public GirlRankBean getGirl_rank() {\n        return girl_rank;\n    }\n\n    public void setGirl_rank(GirlRankBean girl_rank) {\n        this.girl_rank = girl_rank;\n    }\n\n    public List<?> getAdmins() {\n        return admins;\n    }\n\n    public void setAdmins(List<?> admins) {\n        this.admins = admins;\n    }\n\n    public List<?> getNotice() {\n        return notice;\n    }\n\n    public void setNotice(List<?> notice) {\n        this.notice = notice;\n    }\n\n    public List<RoomLine> getRoom_lines() {\n        return room_lines;\n    }\n\n    public void setRoom_lines(List<RoomLine> room_lines) {\n        this.room_lines = room_lines;\n    }\n\n    public List<String> getHot_word() {\n        return hot_word;\n    }\n\n    public void setHot_word(List<String> hot_word) {\n        this.hot_word = hot_word;\n    }\n\n    public List<?> getRank_week() {\n        return rank_week;\n    }\n\n    public void setRank_week(List<?> rank_week) {\n        this.rank_week = rank_week;\n    }\n\n    public List<?> getRank_total() {\n        return rank_total;\n    }\n\n    public void setRank_total(List<?> rank_total) {\n        this.rank_total = rank_total;\n    }\n\n    public List<RankCurrBean> getRank_curr() {\n        return rank_curr;\n    }\n\n    public void setRank_curr(List<RankCurrBean> rank_curr) {\n        this.rank_curr = rank_curr;\n    }\n\n    public static class LiveBean {\n        /**\n         * name : tx\n         * flv : {\"3\":{\"name\":\"标清\",\"src\":\"http://flv3.quanmin.tv/live/3766_326745_550.flv\"},\"4\":{\"name\":\"高清\",\"src\":\"http://flv3.quanmin.tv/live/3766_326745_900.flv\"},\"5\":{\"name\":\"超清\",\"src\":\"http://flv3.quanmin.tv/live/3766_326745.flv\"},\"main_mobile\":3,\"main_pc\":4}\n         * hls : {\"3\":{\"name\":\"标清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745_550.m3u8\"},\"4\":{\"name\":\"高清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745_900.m3u8\"},\"5\":{\"name\":\"超清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745.m3u8\"},\"main_mobile\":3,\"main_pc\":4}\n         * def_mobile : flv\n         * def_pc : flv\n         * v : 1\n         */\n\n        private RoomLine ws;\n\n        public RoomLine getWs() {\n            return ws;\n        }\n\n        public void setWs(RoomLine ws) {\n            this.ws = ws;\n        }\n\n//        public static class WsBean {\n//            private String name;\n//            /**\n//             * 3 : {\"name\":\"标清\",\"src\":\"http://flv3.quanmin.tv/live/3766_326745_550.flv\"}\n//             * 4 : {\"name\":\"高清\",\"src\":\"http://flv3.quanmin.tv/live/3766_326745_900.flv\"}\n//             * 5 : {\"name\":\"超清\",\"src\":\"http://flv3.quanmin.tv/live/3766_326745.flv\"}\n//             * main_mobile : 3\n//             * main_pc : 4\n//             */\n//\n//            private FlvBean flv;\n//            /**\n//             * 3 : {\"name\":\"标清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745_550.m3u8\"}\n//             * 4 : {\"name\":\"高清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745_900.m3u8\"}\n//             * 5 : {\"name\":\"超清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745.m3u8\"}\n//             * main_mobile : 3\n//             * main_pc : 4\n//             */\n//\n//            private HlsBean hls;\n//            private String def_mobile;\n//            private String def_pc;\n//            private String v;\n//\n//            public String getName() {\n//                return name;\n//            }\n//\n//            public void setName(String name) {\n//                this.name = name;\n//            }\n//\n//            public FlvBean getFlv() {\n//                return flv;\n//            }\n//\n//            public void setFlv(FlvBean flv) {\n//                this.flv = flv;\n//            }\n//\n//            public HlsBean getHls() {\n//                return hls;\n//            }\n//\n//            public void setHls(HlsBean hls) {\n//                this.hls = hls;\n//            }\n//\n//            public String getDef_mobile() {\n//                return def_mobile;\n//            }\n//\n//            public void setDef_mobile(String def_mobile) {\n//                this.def_mobile = def_mobile;\n//            }\n//\n//            public String getDef_pc() {\n//                return def_pc;\n//            }\n//\n//            public void setDef_pc(String def_pc) {\n//                this.def_pc = def_pc;\n//            }\n//\n//            public String getV() {\n//                return v;\n//            }\n//\n//            public void setV(String v) {\n//                this.v = v;\n//            }\n//\n//            public static class FlvBean {\n//                /**\n//                 * name : 标清\n//                 * src : http://flv3.quanmin.tv/live/3766_326745_550.flv\n//                 */\n//\n//                @SerializedName(\"3\")\n//                private StreamSrc value3;\n//                /**\n//                 * name : 高清\n//                 * src : http://flv3.quanmin.tv/live/3766_326745_900.flv\n//                 */\n//\n//                @SerializedName(\"4\")\n//                private StreamSrc value4;\n//                /**\n//                 * name : 超清\n//                 * src : http://flv3.quanmin.tv/live/3766_326745.flv\n//                 */\n//\n//                @SerializedName(\"5\")\n//                private StreamSrc value5;\n//                private int main_mobile;\n//                private int main_pc;\n//\n//                public StreamSrc getValue3() {\n//                    return value3;\n//                }\n//\n//                public void setValue3(StreamSrc value3) {\n//                    this.value3 = value3;\n//                }\n//\n//                public StreamSrc getValue4() {\n//                    return value4;\n//                }\n//\n//                public void setValue4(StreamSrc value4) {\n//                    this.value4 = value4;\n//                }\n//\n//                public StreamSrc getValue5() {\n//                    return value5;\n//                }\n//\n//                public void setValue5(StreamSrc value5) {\n//                    this.value5 = value5;\n//                }\n//\n//                public int getMain_mobile() {\n//                    return main_mobile;\n//                }\n//\n//                public void setMain_mobile(int main_mobile) {\n//                    this.main_mobile = main_mobile;\n//                }\n//\n//                public int getMain_pc() {\n//                    return main_pc;\n//                }\n//\n//                public void setMain_pc(int main_pc) {\n//                    this.main_pc = main_pc;\n//                }\n//\n//                public static class StreamSrc {\n//                    private String name;\n//                    private String src;\n//\n//                    public String getName() {\n//                        return name;\n//                    }\n//\n//                    public void setName(String name) {\n//                        this.name = name;\n//                    }\n//\n//                    public String getSrc() {\n//                        return src;\n//                    }\n//\n//                    public void setSrc(String src) {\n//                        this.src = src;\n//                    }\n//                }\n//\n//            }\n//\n//            public static class HlsBean {\n//                /**\n//                 * name : 标清\n//                 * src : http://hls3.quanmin.tv/live/3766_326745_550.m3u8\n//                 */\n//\n//                @SerializedName(\"3\")\n//                private StreamSrc value3;\n//                /**\n//                 * name : 高清\n//                 * src : http://hls3.quanmin.tv/live/3766_326745_900.m3u8\n//                 */\n//\n//                @SerializedName(\"4\")\n//                private StreamSrc value4;\n//                /**\n//                 * name : 超清\n//                 * src : http://hls3.quanmin.tv/live/3766_326745.m3u8\n//                 */\n//\n//                @SerializedName(\"5\")\n//                private StreamSrc value5;\n//                private int main_mobile;\n//                private int main_pc;\n//\n//                public StreamSrc getValue3() {\n//                    return value3;\n//                }\n//\n//                public void setValue3(StreamSrc value3) {\n//                    this.value3 = value3;\n//                }\n//\n//                public StreamSrc getValue4() {\n//                    return value4;\n//                }\n//\n//                public void setValue4(StreamSrc value4) {\n//                    this.value4 = value4;\n//                }\n//\n//                public StreamSrc getValue5() {\n//                    return value5;\n//                }\n//\n//                public void setValue5(StreamSrc value5) {\n//                    this.value5 = value5;\n//                }\n//\n//                public int getMain_mobile() {\n//                    return main_mobile;\n//                }\n//\n//                public void setMain_mobile(int main_mobile) {\n//                    this.main_mobile = main_mobile;\n//                }\n//\n//                public int getMain_pc() {\n//                    return main_pc;\n//                }\n//\n//                public void setMain_pc(int main_pc) {\n//                    this.main_pc = main_pc;\n//                }\n//\n//            }\n//        }\n    }\n\n    public static class GirlRankBean {\n        /**\n         * avatar : http://image.quanmin.tv/avatar/ad569547dfe896f22a7bc5b1d4ecd3d5gif?imageView2/2/w/300/\n         * nick : 浏阳河长的像猴子\n         * uid : 326745\n         * no : 326745\n         * votes : 2430\n         * rank : 43\n         * toPre : 0\n         * rankType : GAME\n         */\n\n        private CurAnchorInfoBean curAnchorInfo;\n        /**\n         * avatar : http://image.quanmin.tv/avatar/4929b40c878e3b572c1eefb27dc06e48png?imageView2/2/w/300/\n         * nick : 全民小龙\n         * uid : 29105\n         * votes : 64860\n         * no : 29105\n         * status : 0\n         */\n\n        private List<Rank> rank;\n\n        public CurAnchorInfoBean getCurAnchorInfo() {\n            return curAnchorInfo;\n        }\n\n        public void setCurAnchorInfo(CurAnchorInfoBean curAnchorInfo) {\n            this.curAnchorInfo = curAnchorInfo;\n        }\n\n        public List<Rank> getRank() {\n            return rank;\n        }\n\n        public void setRank(List<Rank> rank) {\n            this.rank = rank;\n        }\n\n        public static class CurAnchorInfoBean {\n            private String avatar;\n            private String nick;\n            private int uid;\n            private int no;\n            private int votes;\n            private int rank;\n            private int toPre;\n            private String rankType;\n\n            public String getAvatar() {\n                return avatar;\n            }\n\n            public void setAvatar(String avatar) {\n                this.avatar = avatar;\n            }\n\n            public String getNick() {\n                return nick;\n            }\n\n            public void setNick(String nick) {\n                this.nick = nick;\n            }\n\n            public int getUid() {\n                return uid;\n            }\n\n            public void setUid(int uid) {\n                this.uid = uid;\n            }\n\n            public int getNo() {\n                return no;\n            }\n\n            public void setNo(int no) {\n                this.no = no;\n            }\n\n            public int getVotes() {\n                return votes;\n            }\n\n            public void setVotes(int votes) {\n                this.votes = votes;\n            }\n\n            public int getRank() {\n                return rank;\n            }\n\n            public void setRank(int rank) {\n                this.rank = rank;\n            }\n\n            public int getToPre() {\n                return toPre;\n            }\n\n            public void setToPre(int toPre) {\n                this.toPre = toPre;\n            }\n\n            public String getRankType() {\n                return rankType;\n            }\n\n            public void setRankType(String rankType) {\n                this.rankType = rankType;\n            }\n        }\n\n        public static class Rank {\n            private String avatar;\n            private String nick;\n            private int uid;\n            private int votes;\n            private int no;\n            private int status;\n\n            public String getAvatar() {\n                return avatar;\n            }\n\n            public void setAvatar(String avatar) {\n                this.avatar = avatar;\n            }\n\n            public String getNick() {\n                return nick;\n            }\n\n            public void setNick(String nick) {\n                this.nick = nick;\n            }\n\n            public int getUid() {\n                return uid;\n            }\n\n            public void setUid(int uid) {\n                this.uid = uid;\n            }\n\n            public int getVotes() {\n                return votes;\n            }\n\n            public void setVotes(int votes) {\n                this.votes = votes;\n            }\n\n            public int getNo() {\n                return no;\n            }\n\n            public void setNo(int no) {\n                this.no = no;\n            }\n\n            public int getStatus() {\n                return status;\n            }\n\n            public void setStatus(int status) {\n                this.status = status;\n            }\n        }\n    }\n\n    public static class RankCurrBean {\n        private String send_uid;\n        private String send_nick;\n        private String avatar;\n        private int rank;\n        private int score;\n        private String icon;\n\n        public String getSend_uid() {\n            return send_uid;\n        }\n\n        public void setSend_uid(String send_uid) {\n            this.send_uid = send_uid;\n        }\n\n        public String getSend_nick() {\n            return send_nick;\n        }\n\n        public void setSend_nick(String send_nick) {\n            this.send_nick = send_nick;\n        }\n\n        public String getAvatar() {\n            return avatar;\n        }\n\n        public void setAvatar(String avatar) {\n            this.avatar = avatar;\n        }\n\n        public int getRank() {\n            return rank;\n        }\n\n        public void setRank(int rank) {\n            this.rank = rank;\n        }\n\n        public int getScore() {\n            return score;\n        }\n\n        public void setScore(int score) {\n            this.score = score;\n        }\n\n        public String getIcon() {\n            return icon;\n        }\n\n        public void setIcon(String icon) {\n            this.icon = icon;\n        }\n    }\n\n\n    @Override\n    public String toString() {\n        return \"Room{\" +\n                \"uid=\" + uid +\n                \", no=\" + no +\n                \", title='\" + title + '\\'' +\n                \", nick='\" + nick + '\\'' +\n                \", avatar='\" + avatar + '\\'' +\n                \", slug='\" + slug + '\\'' +\n                \", intro='\" + intro + '\\'' +\n                \", category_id='\" + category_id + '\\'' +\n                \", category_name='\" + category_name + '\\'' +\n                \", screen=\" + screen +\n                \", view=\" + view +\n                \", weight=\" + weight +\n                \", follow=\" + follow +\n                \", last_play_at='\" + last_play_at + '\\'' +\n                \", announcement='\" + announcement + '\\'' +\n                \", play_at='\" + play_at + '\\'' +\n                \", thumb='\" + thumb + '\\'' +\n                \", status='\" + status + '\\'' +\n                \", play_status=\" + play_status +\n                \", forbid_status=\" + forbid_status +\n                \", police_forbid=\" + police_forbid +\n                \", hidden=\" + hidden +\n                \", video_quality='\" + video_quality + '\\'' +\n                \", live=\" + live +\n                \", is_star=\" + is_star +\n                \", special=\" + special +\n                \", watermark=\" + watermark +\n                \", watermark_pic='\" + watermark_pic + '\\'' +\n                \", girl_rank=\" + girl_rank +\n                \", admins=\" + admins +\n                \", notice=\" + notice +\n                \", room_lines=\" + room_lines +\n                \", hot_word=\" + hot_word +\n                \", rank_week=\" + rank_week +\n                \", rank_total=\" + rank_total +\n                \", rank_curr=\" + rank_curr +\n                '}';\n    }\n}\n"
  },
  {
    "path": "live/src/main/java/me/shouheng/live/model/data/RoomLine.java",
    "content": "package me.shouheng.live.model.data;\n\nimport com.google.gson.annotations.SerializedName;\n\npublic class RoomLine {\n\n    /**\n     * name : tx\n     * flv : {\"3\":{\"name\":\"标清\",\"src\":\"http://flv3.quanmin.tv/live/3766_326745_550.flv\"},\"4\":{\"name\":\"高清\",\"src\":\"http://flv3.quanmin.tv/live/3766_326745_900.flv\"},\"5\":{\"name\":\"超清\",\"src\":\"http://flv3.quanmin.tv/live/3766_326745.flv\"},\"main_mobile\":3,\"main_pc\":4}\n     * hls : {\"3\":{\"name\":\"标清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745_550.m3u8\"},\"4\":{\"name\":\"高清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745_900.m3u8\"},\"5\":{\"name\":\"超清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745.m3u8\"},\"main_mobile\":3,\"main_pc\":4}\n     * def_mobile : flv\n     * def_pc : flv\n     * v : 1\n     */\n\n    private String name;\n    /**\n     * 3 : {\"name\":\"标清\",\"src\":\"http://flv3.quanmin.tv/live/3766_326745_550.flv\"}\n     * 4 : {\"name\":\"高清\",\"src\":\"http://flv3.quanmin.tv/live/3766_326745_900.flv\"}\n     * 5 : {\"name\":\"超清\",\"src\":\"http://flv3.quanmin.tv/live/3766_326745.flv\"}\n     * main_mobile : 3\n     * main_pc : 4\n     */\n\n    private FlvBean flv;\n    /**\n     * 3 : {\"name\":\"标清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745_550.m3u8\"}\n     * 4 : {\"name\":\"高清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745_900.m3u8\"}\n     * 5 : {\"name\":\"超清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745.m3u8\"}\n     * main_mobile : 3\n     * main_pc : 4\n     */\n\n    private HlsBean hls;\n    /**\n     * hls : {\"3\":{\"name\":\"标清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745_550.m3u8\"},\"4\":{\"name\":\"高清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745_900.m3u8\"},\"5\":{\"name\":\"超清\",\"src\":\"http://hls3.quanmin.tv/live/3766_326745.m3u8\"},\"main_mobile\":3,\"main_pc\":4}\n     * def_mobile : flv\n     * def_pc : flv\n     * v : 1\n     */\n\n    private String def_mobile;\n    private String def_pc;\n    private String v;\n\n    public HlsBean getHls() {\n        return hls;\n    }\n\n    public void setHls(HlsBean hls) {\n        this.hls = hls;\n    }\n\n    public String getDef_mobile() {\n        return def_mobile;\n    }\n\n    public void setDef_mobile(String def_mobile) {\n        this.def_mobile = def_mobile;\n    }\n\n    public String getDef_pc() {\n        return def_pc;\n    }\n\n    public void setDef_pc(String def_pc) {\n        this.def_pc = def_pc;\n    }\n\n    public String getV() {\n        return v;\n    }\n\n    public void setV(String v) {\n        this.v = v;\n    }\n\n    public FlvBean getFlv() {\n        return flv;\n    }\n\n    public void setFlv(FlvBean flv) {\n        this.flv = flv;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public static class FlvBean {\n        /**\n         * name : 标清\n         * src : http://hls3.quanmin.tv/live/3766_326745_550.m3u8\"\n         */\n\n        @SerializedName(\"3\")\n        private StreamSrc value3;\n        /**\n         * name : 高清\n         * src : http://hls3.quanmin.tv/live/3766_326745_900.m3u8\"\n         */\n\n        @SerializedName(\"4\")\n        private StreamSrc value4;\n        /**\n         * name : 超清\n         * src : http://hls3.quanmin.tv/live/3766_326745.m3u8\"\n         */\n\n        @SerializedName(\"5\")\n        private StreamSrc value5;\n        private int main_mobile;\n        private int main_pc;\n\n        public StreamSrc getValue(boolean isShowing){\n            if(isShowing && value5!=null){\n                return value5;\n            }\n            if(value4!=null){\n                return value4;\n            }\n            if(value5!=null){\n                return value5;\n            }\n            return value3;\n        }\n\n        public StreamSrc getValue3() {\n            return value3;\n        }\n\n        public void setValue3(StreamSrc value3) {\n            this.value3 = value3;\n        }\n\n        public StreamSrc getValue4() {\n            return value4;\n        }\n\n        public void setValue4(StreamSrc value4) {\n            this.value4 = value4;\n        }\n\n        public StreamSrc getValue5() {\n            return value5;\n        }\n\n        public void setValue5(StreamSrc value5) {\n            this.value5 = value5;\n        }\n\n        public int getMain_mobile() {\n            return main_mobile;\n        }\n\n        public void setMain_mobile(int main_mobile) {\n            this.main_mobile = main_mobile;\n        }\n\n        public int getMain_pc() {\n            return main_pc;\n        }\n\n        public void setMain_pc(int main_pc) {\n            this.main_pc = main_pc;\n        }\n\n        @Override\n        public String toString() {\n            return \"FlvBean{\" +\n                    \"value3=\" + value3 +\n                    \", value4=\" + value4 +\n                    \", value5=\" + value5 +\n                    \", main_mobile=\" + main_mobile +\n                    \", main_pc=\" + main_pc +\n                    '}';\n        }\n    }\n\n\n    public static class HlsBean {\n        /**\n         * name : 标清\n         * src : http://hls3.quanmin.tv/live/3766_326745_550.m3u8\n         */\n\n        @SerializedName(\"3\")\n        private StreamSrc value3;\n        /**\n         * name : 高清\n         * src : http://hls3.quanmin.tv/live/3766_326745_900.m3u8\n         */\n\n        @SerializedName(\"4\")\n        private StreamSrc value4;\n        /**\n         * name : 超清\n         * src : http://hls3.quanmin.tv/live/3766_326745.m3u8\n         */\n\n        @SerializedName(\"5\")\n        private StreamSrc value5;\n        private int main_mobile;\n        private int main_pc;\n\n\n        public StreamSrc getValue(boolean isShowing){\n            if(isShowing && value5!=null){\n                return value5;\n            }\n            if(value4!=null){\n                return value4;\n            }\n            if(value5!=null){\n                return value5;\n            }\n            return value3;\n        }\n\n        public StreamSrc getValue3() {\n            return value3;\n        }\n\n        public void setValue3(StreamSrc value3) {\n            this.value3 = value3;\n        }\n\n        public StreamSrc getValue4() {\n            return value4;\n        }\n\n        public void setValue4(StreamSrc value4) {\n            this.value4 = value4;\n        }\n\n        public StreamSrc getValue5() {\n            return value5;\n        }\n\n        public void setValue5(StreamSrc value5) {\n            this.value5 = value5;\n        }\n\n        public int getMain_mobile() {\n            return main_mobile;\n        }\n\n        public void setMain_mobile(int main_mobile) {\n            this.main_mobile = main_mobile;\n        }\n\n        public int getMain_pc() {\n            return main_pc;\n        }\n\n        public void setMain_pc(int main_pc) {\n            this.main_pc = main_pc;\n        }\n\n        @Override\n        public String toString() {\n            return \"HlsBean{\" +\n                    \"value3=\" + value3 +\n                    \", value4=\" + value4 +\n                    \", value5=\" + value5 +\n                    \", main_mobile=\" + main_mobile +\n                    \", main_pc=\" + main_pc +\n                    '}';\n        }\n    }\n\n    @Override\n    public String toString() {\n        return \"RoomLine{\" +\n                \"name='\" + name + '\\'' +\n                \", flv=\" + flv +\n                \", hls=\" + hls +\n                \", def_mobile='\" + def_mobile + '\\'' +\n                \", def_pc='\" + def_pc + '\\'' +\n                \", v='\" + v + '\\'' +\n                '}';\n    }\n}\n"
  },
  {
    "path": "live/src/main/java/me/shouheng/live/model/data/StreamSrc.java",
    "content": "package me.shouheng.live.model.data;\n\npublic class StreamSrc {\n\n    private String name;\n\n    private String src;\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public String getSrc() {\n        return src;\n    }\n\n    public void setSrc(String src) {\n        this.src = src;\n    }\n\n    @Override\n    public String toString() {\n        return \"StreamSrc{\" +\n                \"name='\" + name + '\\'' +\n                \", src='\" + src + '\\'' +\n                '}';\n    }\n}\n"
  },
  {
    "path": "live/src/main/java/me/shouheng/live/model/repository/LiveRetrofit.java",
    "content": "package me.shouheng.live.model.repository;\n\nimport java.util.concurrent.TimeUnit;\n\nimport me.shouheng.live.model.LiveService;\nimport okhttp3.OkHttpClient;\nimport retrofit2.Retrofit;\nimport retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;\nimport retrofit2.converter.gson.GsonConverterFactory;\n\n/**\n * Created by WngShhng on 2018/7/30.*/\npublic class LiveRetrofit {\n\n    public static LiveService getLiveService() {\n        return new Retrofit.Builder()\n                .baseUrl(\"http://www.quanmin.tv/\")\n                .addConverterFactory(GsonConverterFactory.create())\n                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())\n                .client(getOkHttpClient())\n                .build()\n                .create(LiveService.class);\n    }\n\n    private static OkHttpClient getOkHttpClient() {\n        return new OkHttpClient.Builder()\n                .connectTimeout(10, TimeUnit.SECONDS)\n                .readTimeout(10, TimeUnit.SECONDS)\n                .writeTimeout(10, TimeUnit.SECONDS)\n                .build();\n    }\n}\n"
  },
  {
    "path": "live/src/main/java/me/shouheng/live/view/Constant.java",
    "content": "package me.shouheng.live.view;\n\n/**\n * @author shouh\n * @version $Id: Constant, v 0.1 2018/6/9 10:46 shouh Exp$\n */\npublic class Constant {\n\n    public static final String SHOWING = \"showing\";\n}\n"
  },
  {
    "path": "live/src/main/java/me/shouheng/live/view/activity/LiveActivity.java",
    "content": "package me.shouheng.live.view.activity;\n\nimport androidx.lifecycle.ViewModelProviders;\nimport android.content.Context;\nimport android.os.Bundle;\nimport androidx.appcompat.app.ActionBar;\nimport androidx.recyclerview.widget.LinearLayoutManager;\nimport androidx.appcompat.widget.Toolbar;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.ImageView;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.alibaba.android.arouter.launcher.ARouter;\nimport com.bigkoo.convenientbanner.ConvenientBanner;\nimport com.bigkoo.convenientbanner.holder.Holder;\nimport com.bumptech.glide.load.engine.DiskCacheStrategy;\n\nimport java.util.LinkedList;\nimport java.util.List;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.ToastUtils;\nimport me.shouheng.commons.tools.glide.GlideApp;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.live.R;\nimport me.shouheng.live.databinding.ActivityLiveBinding;\nimport me.shouheng.live.model.data.Banner;\nimport me.shouheng.live.model.data.Recommend;\nimport me.shouheng.live.view.Constant;\nimport me.shouheng.live.view.adapter.RecommendAdapter;\nimport me.shouheng.live.viewmodel.LiveViewModel;\n\n@Route(path = BaseConstants.LIVE_HOME)\npublic class LiveActivity extends CommonActivity<ActivityLiveBinding> {\n\n    private LiveViewModel liveViewModel;\n\n    private RecommendAdapter recommendAdapter;\n\n    private ConvenientBanner<Banner> convenientBanner;\n\n    private List<Banner> banners = new LinkedList<>();\n\n    private List<Recommend.RoomBean> roomBeans = new LinkedList<>();\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_live;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        liveViewModel = ViewModelProviders.of(this).get(LiveViewModel.class);\n\n        configToolbar();\n\n        configList();\n\n        configBanner();\n\n        fetchAppStart();\n\n        fetchRecommend();\n    }\n\n    private void configToolbar() {\n        Toolbar toolbar = getBinding().barLayout.toolbar;\n        toolbar.setBackgroundResource(R.color.light_theme_background);\n        setSupportActionBar(toolbar);\n        ActionBar actionBar = getSupportActionBar();\n        if (actionBar != null) {\n            actionBar.setTitle(R.string.live_title);\n            actionBar.setSubtitle(R.string.live_sub_title);\n        }\n    }\n\n    private void configList() {\n        recommendAdapter = new RecommendAdapter(this);\n        recommendAdapter.setOnRoomClickListener(this::startRoom);\n        recommendAdapter.setOnItemChildClickListener(((adapter, view, position) -> {\n            if (view.getId() == R.id.tv_more) {\n                // todo when click more\n                ToastUtils.makeToast(\"More\");\n            }\n        }));\n\n        getBinding().rv.setLayoutManager(new LinearLayoutManager(this));\n        getBinding().rv.setAdapter(recommendAdapter);\n    }\n\n    private void startRoom(Recommend.RoomBean.ListBean listBean) {\n        ARouter.getInstance()\n                .build(BaseConstants.LIVE_DETAIL)\n                .withInt(BaseConstants.LIVE_DETAIL_EXTRA_ROOM_TYPE,\n                        Constant.SHOWING.equalsIgnoreCase(listBean.getCategory_slug()) ?\n                        LiveRoomActivity.RoomType.FULL_SCREEN.id : LiveRoomActivity.RoomType.SUB_SCREEN.id)\n                .withString(BaseConstants.LIVE_DETAIL_EXTRA_UID, String.valueOf(listBean.getUid()))\n                .withString(BaseConstants.LIVE_DETAIL_EXTRA_THUMB, listBean.getThumb())\n                .navigation();\n    }\n\n    private void configBanner() {\n        View view = getLayoutInflater().inflate(R.layout.layout_banner, null, false);\n        convenientBanner = view.findViewById(R.id.cb);\n        convenientBanner.setOnItemClickListener(position -> {\n            // todo banner event\n            ToastUtils.makeToast(\"Banner\");\n        });\n        convenientBanner.setPages(ImageHolder::new, banners)\n                .setPageIndicator(new int[]{R.drawable.ic_dot_normal, R.drawable.ic_dot_pressed})\n                .setPageIndicatorAlign(ConvenientBanner.PageIndicatorAlign.CENTER_HORIZONTAL);\n        if(!convenientBanner.isTurning()) {\n            convenientBanner.startTurning(4000);\n        }\n\n        recommendAdapter.addHeaderView(view);\n    }\n\n    public class ImageHolder implements Holder<Banner> {\n\n        private ImageView iv;\n\n        @Override\n        public View createView(Context context) {\n            iv = new ImageView(context);\n            iv.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,\n                    ViewGroup.LayoutParams.MATCH_PARENT));\n            iv.setScaleType(ImageView.ScaleType.CENTER_CROP);\n            return iv;\n        }\n\n        @Override\n        public void UpdateUI(Context context, int position, Banner data) {\n            GlideApp.with(context)\n                    .load(data.getThumb())\n                    .placeholder(R.drawable.live_default)\n                    .error(R.drawable.live_default)\n                    .centerCrop()\n                    .diskCacheStrategy(DiskCacheStrategy.RESOURCE)\n                    .into(iv);\n        }\n    }\n\n    private void fetchRecommend() {\n        liveViewModel.getRecommend().observe(this, recommendResource -> {\n            if (recommendResource == null) {\n                return;\n            }\n            switch (recommendResource.status) {\n                case SUCCESS:\n                    recommendAdapter.setNewData(roomBeans = recommendResource.data.getRoom());\n                    break;\n                case FAILED:\n                    ToastUtils.makeToast(recommendResource.message);\n                    break;\n            }\n        });\n    }\n\n    private void fetchAppStart() {\n        liveViewModel.getAppStart().observe(this, appStartResource -> {\n            if (appStartResource == null) {\n                return;\n            }\n            switch (appStartResource.status) {\n                case FAILED:\n                    ToastUtils.makeToast(appStartResource.message);\n                    break;\n                case SUCCESS:\n                    banners.clear();\n                    banners.addAll(appStartResource.data.getBanners());\n                    convenientBanner.notifyDataSetChanged();\n                    break;\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "live/src/main/java/me/shouheng/live/view/activity/LiveRoomActivity.java",
    "content": "package me.shouheng.live.view.activity;\n\nimport android.content.Intent;\nimport android.content.pm.ActivityInfo;\nimport android.os.Bundle;\nimport androidx.fragment.app.Fragment;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.alibaba.android.arouter.launcher.ARouter;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.FragmentHelper;\nimport me.shouheng.commons.tools.theme.ThemeUtils;\nimport me.shouheng.commons.view.activity.CommonActivity;\nimport me.shouheng.commons.view.fragment.CommonFragment;\nimport me.shouheng.live.R;\nimport me.shouheng.live.databinding.ActivityLiveRoomBinding;\n\n/**\n * @author shouh\n * @version $Id: LiveRoomActivity, v 0.1 2018/6/9 10:32 shouh Exp$\n */\n@Route(path = BaseConstants.LIVE_DETAIL)\npublic class LiveRoomActivity extends CommonActivity<ActivityLiveRoomBinding> {\n\n    public enum RoomType {\n        SUB_SCREEN(0),\n        FULL_SCREEN(1);\n\n        public final int id;\n\n        RoomType(int id) {\n            this.id = id;\n        }\n\n        public static RoomType getTypeById(int id) {\n            for (RoomType roomType : values()) {\n                if (roomType.id == id) {\n                    return roomType;\n                }\n            }\n            throw new IllegalArgumentException(\"Invalid room type id\");\n        }\n    }\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.activity_live_room;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        Intent intent = getIntent();\n        int roomTypeId = intent.getIntExtra(BaseConstants.LIVE_DETAIL_EXTRA_ROOM_TYPE, 0);\n        RoomType roomType = RoomType.getTypeById(roomTypeId);\n        String uid = intent.getStringExtra(BaseConstants.LIVE_DETAIL_EXTRA_UID);\n        String thumb = intent.getStringExtra(BaseConstants.LIVE_DETAIL_EXTRA_THUMB);\n        switch (roomType) {\n            case SUB_SCREEN: {\n                Fragment fragment = (Fragment) ARouter.getInstance()\n                        .build(BaseConstants.LIVE_DETAIL_ROOM)\n                        .withString(BaseConstants.LIVE_DETAIL_ROOM_EXTRA_KEY_UID, uid)\n                        .withString(BaseConstants.LIVE_DETAIL_ROOM_EXTRA_KEY_THUMB, thumb)\n                        .navigation();\n                toFragment(fragment);\n                break;\n            }\n            case FULL_SCREEN: {\n                Fragment fragment = (Fragment) ARouter.getInstance()\n                        .build(BaseConstants.LIVE_DETAIL_FULL_SCREEN)\n                        .withString(BaseConstants.LIVE_DETAIL_FULL_SCREEN_EXTRA_KEY_UID, uid)\n                        .withString(BaseConstants.LIVE_DETAIL_FULL_SCREEN_EXTRA_KEY_THUMB, thumb)\n                        .navigation();\n                toFragment(fragment);\n                break;\n            }\n        }\n\n        if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {\n            ThemeUtils.hideSystemUI(this);\n        }\n    }\n\n    private void toFragment(Fragment fragment) {\n        FragmentHelper.replace(this, fragment, R.id.fragment_container);\n    }\n\n    private Fragment getCurrentFragment() {\n        return getCurrentFragment(R.id.fragment_container);\n    }\n\n    @Override\n    public void onBackPressed() {\n        Fragment fragment = getCurrentFragment();\n        if (fragment instanceof CommonFragment) {\n            ((CommonFragment) fragment).onBackPressed();\n        } else {\n            super.onBackPressed();\n        }\n    }\n}\n"
  },
  {
    "path": "live/src/main/java/me/shouheng/live/view/adapter/RecommendAdapter.java",
    "content": "package me.shouheng.live.view.adapter;\n\nimport android.content.Context;\nimport androidx.recyclerview.widget.GridLayoutManager;\nimport androidx.recyclerview.widget.RecyclerView;\nimport android.widget.ImageView;\n\nimport com.chad.library.adapter.base.BaseQuickAdapter;\nimport com.chad.library.adapter.base.BaseViewHolder;\n\nimport java.util.Collections;\n\nimport me.shouheng.commons.tools.glide.GlideApp;\nimport me.shouheng.live.R;\nimport me.shouheng.live.model.data.Recommend;\n\n/**\n * @author shouh\n * @version $Id: RecommendAdapter, v 0.1 2018/6/9 7:01 shouh Exp$\n */\npublic class RecommendAdapter extends BaseQuickAdapter<Recommend.RoomBean, BaseViewHolder> {\n\n    private Context context;\n\n    private OnRoomClickListener onRoomClickListener;\n\n    public RecommendAdapter(Context context) {\n        super(R.layout.item_remmend, Collections.emptyList());\n        this.context = context;\n    }\n\n    @Override\n    protected void convert(BaseViewHolder helper, Recommend.RoomBean item) {\n        helper.setText(R.id.tv_category, item.getName());\n\n        GlideApp.with(context)\n                .load(item.getIcon())\n                .placeholder(R.drawable.live_default_recommend_icon)\n                .into((ImageView) helper.getView(R.id.iv_category));\n\n        helper.addOnClickListener(R.id.tv_more);\n\n        RecommendChildAdapter adapter = new RecommendChildAdapter(context, item.getList());\n        adapter.setOnItemClickListener(((adapter1, view, position) -> {\n            if (onRoomClickListener != null) {\n                Recommend.RoomBean.ListBean listBean = item.getList().get(position);\n                onRoomClickListener.onRoomClick(listBean);\n            }\n        }));\n\n        RecyclerView rv = helper.getView(R.id.rv);\n        rv.setLayoutManager(new GridLayoutManager(context, 2));\n        rv.setAdapter(adapter);\n    }\n\n    public void setOnRoomClickListener(OnRoomClickListener onRoomClickListener) {\n        this.onRoomClickListener = onRoomClickListener;\n    }\n\n    public interface OnRoomClickListener {\n        void onRoomClick(Recommend.RoomBean.ListBean listBean);\n    }\n}\n"
  },
  {
    "path": "live/src/main/java/me/shouheng/live/view/adapter/RecommendChildAdapter.java",
    "content": "package me.shouheng.live.view.adapter;\n\nimport android.content.Context;\nimport android.graphics.Bitmap;\nimport androidx.palette.graphics.Palette;\nimport android.util.SparseIntArray;\n\nimport com.bumptech.glide.Glide;\nimport com.bumptech.glide.request.target.BitmapImageViewTarget;\nimport com.chad.library.adapter.base.BaseQuickAdapter;\nimport com.chad.library.adapter.base.BaseViewHolder;\n\nimport java.util.List;\n\nimport me.shouheng.commons.tools.ColorUtils;\nimport me.shouheng.live.R;\nimport me.shouheng.live.model.data.Recommend;\n\n/**\n * @author shouh\n * @version $Id: RecommendChildAdapter, v 0.1 2018/6/9 7:16 shouh Exp$\n */\npublic class RecommendChildAdapter extends BaseQuickAdapter<Recommend.RoomBean.ListBean, BaseViewHolder> {\n\n    private Context context;\n\n    private SparseIntArray array;\n\n    RecommendChildAdapter(Context context, List<Recommend.RoomBean.ListBean> beanList) {\n        super(R.layout.item_remmend_child, beanList);\n        this.context = context;\n        array = new SparseIntArray();\n    }\n\n    @Override\n    protected void convert(BaseViewHolder helper, Recommend.RoomBean.ListBean item) {\n        helper.setText(R.id.tv_title, item.getTitle());\n        helper.setText(R.id.tv_name, item.getNick());\n        helper.setText(R.id.tv_viewer, item.getViews());\n\n        Glide.with(context)\n                .asBitmap()\n                .load(item.getThumb())\n                .error(Glide.with(context).asBitmap().load(R.drawable.live_default))\n                .into(new BitmapImageViewTarget(helper.getView(R.id.iv)) {\n                    @Override\n                    protected void setResource(Bitmap resource) {\n                        super.setResource(resource);\n                        setColorPlatte(resource, helper, item);\n                    }\n                });\n    }\n\n    private void setColorPlatte(Bitmap resource, BaseViewHolder helper, Recommend.RoomBean.ListBean item) {\n        int color = array.get(item.getNo());\n        if (color == 0 && resource != null) {\n            new Palette.Builder(resource).generate(palette -> {\n                Palette.Swatch swatch = palette.getVibrantSwatch();\n                int retColor = 0;\n                if (swatch != null) {\n                    retColor = swatch.getRgb();\n                    array.put(item.getNo(), retColor);\n                } else {\n                    Palette.Swatch mutedSwatch = palette.getMutedSwatch();\n                    if (mutedSwatch != null) {\n                        retColor = mutedSwatch.getRgb();\n                        array.put(item.getNo(), retColor);\n                    }\n                }\n                if (retColor != 0) {\n                    helper.setBackgroundColor(R.id.ll, retColor);\n                    int txtColor = ColorUtils.getBlackWhiteColor(retColor);\n                    helper.setTextColor(R.id.tv_name, txtColor);\n                    helper.setTextColor(R.id.tv_viewer, txtColor);\n                }\n            });\n        } else {\n            helper.setBackgroundColor(R.id.ll, color);\n            int txtColor = ColorUtils.getBlackWhiteColor(color);\n            helper.setTextColor(R.id.tv_name, txtColor);\n            helper.setTextColor(R.id.tv_viewer, txtColor);\n        }\n    }\n}\n"
  },
  {
    "path": "live/src/main/java/me/shouheng/live/view/fragment/FullscreenFragment.java",
    "content": "package me.shouheng.live.view.fragment;\n\nimport androidx.lifecycle.ViewModelProviders;\nimport android.os.Bundle;\nimport androidx.annotation.Nullable;\nimport androidx.fragment.app.Fragment;\nimport androidx.fragment.app.FragmentManager;\nimport androidx.fragment.app.FragmentTransaction;\nimport android.view.WindowManager;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.bumptech.glide.Glide;\nimport com.bumptech.glide.load.engine.DiskCacheStrategy;\n\nimport java.util.Objects;\n\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.LogUtils;\nimport me.shouheng.commons.tools.StringUtils;\nimport me.shouheng.commons.tools.ToastUtils;\nimport me.shouheng.commons.tools.glide.GlideApp;\nimport me.shouheng.commons.view.fragment.CommonFragment;\nimport me.shouheng.live.R;\nimport me.shouheng.live.databinding.FragmentFullscreenBinding;\nimport me.shouheng.live.model.data.Room;\nimport me.shouheng.live.model.data.RoomLine;\nimport me.shouheng.live.viewmodel.LiveViewModel;\n\n/**\n * @author shouh\n * @version $Id: FullscreenFragment, v 0.1 2018/6/9 20:00 shouh Exp$\n */\n@Route(path = BaseConstants.LIVE_DETAIL_FULL_SCREEN)\npublic class FullscreenFragment extends CommonFragment<FragmentFullscreenBinding> {\n\n    private String uid, thumb;\n\n    private LiveViewModel liveViewModel;\n\n    private VideoFragment videoFragment;\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.fragment_fullscreen;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        assert getArguments() != null;\n        uid = getArguments().getString(BaseConstants.LIVE_DETAIL_FULL_SCREEN_EXTRA_KEY_UID);\n        thumb = getArguments().getString(BaseConstants.LIVE_DETAIL_FULL_SCREEN_EXTRA_KEY_THUMB);\n\n        liveViewModel = ViewModelProviders.of(this).get(LiveViewModel.class);\n\n        Objects.requireNonNull(getActivity()).getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\n\n        Glide.with(getActivity())\n                .asBitmap()\n                .load(thumb)\n                .into(getBinding().ivCover);\n\n        enterRoom();\n\n        configViews();\n    }\n\n    private void enterRoom() {\n        liveViewModel.enterRoom(uid).observe(this, roomResource -> {\n            if (roomResource == null) {\n                return;\n            }\n            switch (roomResource.status) {\n                case SUCCESS:\n                    Room room = roomResource.data;\n                    LogUtils.d(room);\n                    showRoomInfo(room);\n                    if(room != null){\n                        String url;\n                        RoomLine roomLine = room.getLive().getWs();\n                        RoomLine.FlvBean flv = roomLine.getFlv();\n                        if (flv != null) {\n                            url = flv.getValue(false).getSrc();\n                        } else {\n                            url = roomLine.getHls().getValue(false).getSrc();\n                        }\n                        playUrl(url);\n                    }\n                    break;\n                case FAILED:\n                    ToastUtils.makeToast(roomResource.message);\n                    break;\n            }\n        });\n    }\n\n    private void playUrl(String url) {\n        if (videoFragment == null) {\n            videoFragment = VideoFragment.newInstance(url,false);\n        }\n        showVideoFragment(videoFragment);\n    }\n\n    private void showVideoFragment(Fragment videoFragment) {\n        FragmentManager manager = getFragmentManager();\n        assert manager != null;\n        FragmentTransaction transaction = manager.beginTransaction();\n        transaction.replace(R.id.rl_video, videoFragment).commit();\n    }\n\n    private void showRoomInfo(@Nullable Room room) {\n        if (room == null) return;\n\n        GlideApp.with(this).load(room.getAvatar())\n                .placeholder(R.drawable.mine_default_avatar)\n                .error(R.drawable.mine_default_avatar).centerCrop()\n                .diskCacheStrategy(DiskCacheStrategy.RESOURCE)\n                .into(getBinding().ivAvatar);\n        getBinding().tvName.setText(room.getNick());\n        getBinding().tvFollow.setText(StringUtils.formatString(R.string.live_follows_number, room.getFollow()));\n\n        getBinding().tvAccount.setText(String.format(getString(R.string.live_qm_account), uid));\n    }\n\n    private void configViews() {\n        getBinding().ivBack.setOnClickListener(v -> onBack());\n        getBinding().ivGift.setOnClickListener(v -> getBinding().ftl.addHeart());\n    }\n\n    private void onBack() {\n        Objects.requireNonNull(getActivity()).finish();\n    }\n\n    @Override\n    public void onBackPressed() {\n        onBack();\n    }\n}\n"
  },
  {
    "path": "live/src/main/java/me/shouheng/live/view/fragment/RoomFragment.java",
    "content": "package me.shouheng.live.view.fragment;\n\nimport androidx.lifecycle.ViewModelProviders;\nimport android.content.pm.ActivityInfo;\nimport android.content.res.Configuration;\nimport android.os.Bundle;\nimport androidx.annotation.Nullable;\nimport androidx.fragment.app.Fragment;\nimport androidx.fragment.app.FragmentManager;\nimport androidx.fragment.app.FragmentTransaction;\nimport android.view.View;\nimport android.view.WindowManager;\nimport android.widget.LinearLayout;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.bumptech.glide.Glide;\n\nimport java.util.Objects;\n\nimport me.shouheng.commons.BaseApplication;\nimport me.shouheng.commons.config.BaseConstants;\nimport me.shouheng.commons.tools.LogUtils;\nimport me.shouheng.commons.tools.StringUtils;\nimport me.shouheng.commons.tools.ToastUtils;\nimport me.shouheng.commons.tools.ViewUtils;\nimport me.shouheng.commons.view.fragment.CommonFragment;\nimport me.shouheng.live.R;\nimport me.shouheng.live.databinding.FragmentRoomBinding;\nimport me.shouheng.live.model.data.Room;\nimport me.shouheng.live.model.data.RoomLine;\nimport me.shouheng.live.viewmodel.LiveViewModel;\n\n/**\n * @author shouh\n * @version $Id: RoomFragment, v 0.1 2018/6/9 10:59 shouh Exp$\n */\n@Route(path = BaseConstants.LIVE_DETAIL_ROOM)\npublic class RoomFragment extends CommonFragment<FragmentRoomBinding> {\n\n    private String uid, thumb;\n\n    private LiveViewModel liveViewModel;\n\n    private VideoFragment videoFragment;\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.fragment_room;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        assert getArguments() != null;\n        uid = getArguments().getString(BaseConstants.LIVE_DETAIL_ROOM_EXTRA_KEY_UID);\n        thumb = getArguments().getString(BaseConstants.LIVE_DETAIL_ROOM_EXTRA_KEY_THUMB);\n\n        liveViewModel = ViewModelProviders.of(this).get(LiveViewModel.class);\n\n        Objects.requireNonNull(getActivity()).getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\n\n        configLayout();\n\n        enterRoom();\n\n        configViews();\n    }\n\n    private void enterRoom() {\n        liveViewModel.enterRoom(uid).observe(this, roomResource -> {\n            if (roomResource == null) {\n                return;\n            }\n            switch (roomResource.status) {\n                case SUCCESS:\n                    Room room = roomResource.data;\n                    LogUtils.d(room);\n                    showRoomInfo(room);\n                    if(room != null){\n                        String url;\n                        RoomLine roomLine = room.getLive().getWs();\n                        RoomLine.FlvBean flv = roomLine.getFlv();\n                        if(flv != null){\n                            url = flv.getValue(false).getSrc();\n                        }else{\n                            url = roomLine.getHls().getValue(false).getSrc();\n                        }\n                        playUrl(url);\n                    }\n                    break;\n                case FAILED:\n                    ToastUtils.makeToast(roomResource.message);\n                    break;\n            }\n        });\n    }\n\n    private void configLayout() {\n        boolean landscape = landscape();\n        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) getBinding().rlContainer.getLayoutParams();\n        lp.height = landscape ? ViewUtils.getDisplayMetrics().heightPixels :\n                (int) (ViewUtils.getDisplayMetrics().widthPixels * 9.0f / 16.0f);\n        lp.topMargin = landscape ? 0 : ViewUtils.getStatusBarHeight(BaseApplication.getContext());\n        getBinding().rlContainer.setLayoutParams(lp);\n    }\n\n    private void configViews() {\n        getBinding().ivFullScreen.setOnClickListener(v ->\n                Objects.requireNonNull(getActivity()).setRequestedOrientation(landscape() ?\n                        ActivityInfo.SCREEN_ORIENTATION_PORTRAIT : ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE));\n        getBinding().ivBack.setOnClickListener(v -> onBack());\n    }\n\n    private void playUrl(String url) {\n        if (videoFragment == null) {\n            videoFragment = VideoFragment.newInstance(url,false);\n        }\n        showVideoFragment(videoFragment);\n    }\n\n    private void showRoomInfo(@Nullable Room room) {\n        if (room == null) return;\n\n        getBinding().tvTitle.setText(room.getTitle());\n        getBinding().tvViews.setText(StringUtils.formatString(R.string.live_views_number, room.getView()));\n        getBinding().tvAnno.setText(room.getAnnouncement());\n\n        Glide.with(getContext()).asBitmap().load(room.getAvatar()).into(getBinding().ivAvatar);\n        getBinding().tvUserName.setText(room.getNick());\n        getBinding().tvFollow.setText(StringUtils.formatString(R.string.live_follows_number, room.getFollow()));\n        getBinding().tvUserIntro.setText(room.getIntro());\n    }\n\n    private void showVideoFragment(Fragment videoFragment) {\n        FragmentManager manager = getFragmentManager();\n        assert manager != null;\n        FragmentTransaction transaction = manager.beginTransaction();\n        transaction.replace(R.id.rl_video, videoFragment).commit();\n    }\n\n    private boolean landscape() {\n        return Objects.requireNonNull(getActivity()).getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;\n    }\n\n    private void onBack() {\n        if (landscape()) {\n            Objects.requireNonNull(getActivity()).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);\n        } else {\n            Objects.requireNonNull(getActivity()).finish();\n        }\n    }\n\n    @Override\n    public void onConfigurationChanged(Configuration newConfig) {\n        super.onConfigurationChanged(newConfig);\n        boolean landscape = landscape();\n        getBinding().ivFullScreen.setVisibility(landscape ? View.GONE : View.VISIBLE);\n        configLayout();\n    }\n\n    @Override\n    public void onBackPressed() {\n        onBack();\n    }\n}\n"
  },
  {
    "path": "live/src/main/java/me/shouheng/live/view/fragment/VideoFragment.java",
    "content": "package me.shouheng.live.view.fragment;\n\nimport android.os.Bundle;\nimport android.view.View;\n\nimport com.pili.pldroid.player.widget.PLVideoTextureView;\nimport com.pili.pldroid.player.widget.PLVideoView;\n\nimport me.shouheng.commons.tools.LogUtils;\nimport me.shouheng.commons.view.fragment.CommonFragment;\nimport me.shouheng.live.R;\nimport me.shouheng.live.databinding.FragmentVideoBinding;\n\n/**\n * @author shouh\n * @version $Id: VideoFragment, v 0.1 2018/6/9 14:19 shouh Exp$\n */\npublic class VideoFragment extends CommonFragment<FragmentVideoBinding> {\n\n    private final static String EXTRA_URL = \"__extra_url\";\n\n    private final static String EXTRA_FULLSCREEN = \"__extra_fullscreen\";\n\n    private String url;\n\n    private boolean fullscreen;\n\n    private int mRotation;\n\n    public static VideoFragment newInstance(String url, boolean fullscreen) {\n        Bundle args = new Bundle();\n        args.putString(EXTRA_URL, url);\n        args.putBoolean(EXTRA_FULLSCREEN, fullscreen);\n        VideoFragment fragment = new VideoFragment();\n        fragment.setArguments(args);\n        return fragment;\n    }\n\n    @Override\n    protected int getLayoutResId() {\n        return R.layout.fragment_video;\n    }\n\n    @Override\n    protected void doCreateView(Bundle savedInstanceState) {\n        handleArgument();\n\n        configVideo();\n    }\n\n    private void handleArgument() {\n        Bundle args = getArguments();\n        assert args != null;\n        url = args.getString(EXTRA_URL);\n        fullscreen = args.getBoolean(EXTRA_FULLSCREEN);\n    }\n\n    private void configVideo() {\n        getBinding().vtv.setVideoPath(url);\n        getBinding().vtv.setDisplayOrientation(fullscreen ? PLVideoView.ASPECT_RATIO_PAVED_PARENT : PLVideoView.ASPECT_RATIO_16_9);\n        getBinding().vtv.setOnPreparedListener(plMediaPlayer -> start());\n        getBinding().vtv.setOnBufferingUpdateListener((plMediaPlayer, i) -> LogUtils.d(i + \"\"));\n        getBinding().vtv.setOnCompletionListener(plMediaPlayer -> LogUtils.d(\"completion\"));\n        getBinding().vtv.setOnInfoListener((plMediaPlayer, i, i1) -> {\n            LogUtils.d(i + \"--i1:\" + i1);\n            return false;\n        });\n        getBinding().vtv.setOnErrorListener((plMediaPlayer, i) -> {\n            LogUtils.d(i + \"\");\n            return false;\n        });\n    }\n\n    public void play(String url){\n        this.url = url;\n        getBinding().vtv.setVideoPath(url);\n        getBinding().vtv.start();\n    }\n\n    private void start(){\n        getBinding().vtv.start();\n    }\n\n    public void pause(){\n        getBinding().vtv.pause();\n    }\n\n    public void stopPlayback(){\n        getBinding().vtv.stopPlayback();\n    }\n\n    public void seekTo(long i){\n        getBinding().vtv.seekTo(i);\n    }\n\n    public boolean isPlaying(){\n        return getBinding().vtv.isPlaying();\n    }\n\n    public PLVideoTextureView getVideoView(){\n        return getBinding().vtv;\n    }\n\n    public int getDisplayAspectRatio(){\n        return getBinding().vtv.getDisplayAspectRatio();\n    }\n\n    public void onClickRotate(View v) {\n        mRotation = (getBinding().vtv.getDisplayAspectRatio() + 90) % 360;\n        setDisplayAspectRatio(mRotation);\n    }\n\n    /**\n     * Should be one of below:\n     * {@link PLVideoView#ASPECT_RATIO_4_3}\n     * {@link PLVideoView#ASPECT_RATIO_16_9}\n     * {@link PLVideoView#ASPECT_RATIO_PAVED_PARENT}\n     * {@link PLVideoView#ASPECT_RATIO_FIT_PARENT}\n     * {@link PLVideoView#ASPECT_RATIO_ORIGIN}\n     *\n     * @param ratio see above */\n    public void setDisplayAspectRatio(int ratio){\n        getBinding().vtv.setDisplayAspectRatio(ratio);\n    }\n\n    public void setDisplayOrientation(int orientation){\n        getBinding().vtv.setDisplayOrientation(orientation);\n    }\n\n    @Override\n    public void onResume() {\n        super.onResume();\n        start();\n    }\n\n    @Override\n    public void onPause() {\n        super.onPause();\n        pause();\n    }\n\n    @Override\n    public void onDestroy() {\n        super.onDestroy();\n        stopPlayback();\n    }\n}\n"
  },
  {
    "path": "live/src/main/java/me/shouheng/live/viewmodel/LiveViewModel.java",
    "content": "package me.shouheng.live.viewmodel;\n\nimport androidx.lifecycle.LiveData;\nimport androidx.lifecycle.MutableLiveData;\nimport androidx.lifecycle.ViewModel;\n\nimport io.reactivex.Observer;\nimport io.reactivex.android.schedulers.AndroidSchedulers;\nimport io.reactivex.disposables.Disposable;\nimport io.reactivex.schedulers.Schedulers;\nimport me.shouheng.commons.model.Resource;\nimport me.shouheng.live.model.data.AppStart;\nimport me.shouheng.live.model.data.Recommend;\nimport me.shouheng.live.model.data.Room;\nimport me.shouheng.live.model.repository.LiveRetrofit;\n\n/**\n * @author shouh\n * @version $Id: LiveViewModel, v 0.1 2018/6/8 22:13 shouh Exp$\n */\npublic class LiveViewModel extends ViewModel {\n\n    public LiveData<Resource<Recommend>> getRecommend() {\n        MutableLiveData<Resource<Recommend>> result = new MutableLiveData<>();\n        LiveRetrofit.getLiveService().getRecommend()\n                .subscribeOn(Schedulers.io())\n                .observeOn(AndroidSchedulers.mainThread())\n                .subscribe(new Observer<Recommend>() {\n                    @Override\n                    public void onSubscribe(Disposable d) { }\n\n                    @Override\n                    public void onNext(Recommend recommend) {\n                        result.setValue(Resource.success(recommend));\n                    }\n\n                    @Override\n                    public void onError(Throwable e) {\n                        result.setValue(Resource.error(e.getMessage(), null));\n                    }\n\n                    @Override\n                    public void onComplete() { }\n                });\n        return result;\n    }\n\n    public LiveData<Resource<AppStart>> getAppStart() {\n        MutableLiveData<Resource<AppStart>> result = new MutableLiveData<>();\n        LiveRetrofit.getLiveService().getAppStartInfo()\n                .subscribeOn(Schedulers.io())\n                .observeOn(AndroidSchedulers.mainThread())\n                .subscribe(new Observer<AppStart>() {\n                    @Override\n                    public void onError(Throwable e) {\n                        result.setValue(Resource.error(e.getMessage(), null));\n                    }\n\n                    @Override\n                    public void onComplete() { }\n\n                    @Override\n                    public void onSubscribe(Disposable d) { }\n\n                    @Override\n                    public void onNext(AppStart appStart) {\n                        result.setValue(Resource.success(appStart));\n                    }\n                });\n        return result;\n    }\n\n    public LiveData<Resource<Room>> enterRoom(String uid) {\n        MutableLiveData<Resource<Room>> result = new MutableLiveData<>();\n        LiveRetrofit.getLiveService().enterRoom(uid)\n                .subscribeOn(Schedulers.io())\n                .observeOn(AndroidSchedulers.mainThread())\n                .subscribe(new Observer<Room>() {\n                    @Override\n                    public void onError(Throwable e) {\n                        result.setValue(Resource.error(e.getMessage(), null));\n                    }\n\n                    @Override\n                    public void onComplete() { }\n\n                    @Override\n                    public void onSubscribe(Disposable d) { }\n\n                    @Override\n                    public void onNext(Room room) {\n                        result.setValue(Resource.success(room));\n                    }\n                });\n        return result;\n    }\n}\n"
  },
  {
    "path": "live/src/main/res/drawable/full_room_avatar_bg.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <corners android:radius=\"17dp\"/>\n    <solid android:color=\"#1f000000\"/>\n</shape>"
  },
  {
    "path": "live/src/main/res/drawable/ic_arrow_back_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24.0\"\n        android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z\"/>\n</vector>\n"
  },
  {
    "path": "live/src/main/res/drawable/ic_card_giftcard_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24.0\"\n        android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M20,6h-2.18c0.11,-0.31 0.18,-0.65 0.18,-1 0,-1.66 -1.34,-3 -3,-3 -1.05,0 -1.96,0.54 -2.5,1.35l-0.5,0.67 -0.5,-0.68C10.96,2.54 10.05,2 9,2 7.34,2 6,3.34 6,5c0,0.35 0.07,0.69 0.18,1L4,6c-1.11,0 -1.99,0.89 -1.99,2L2,19c0,1.11 0.89,2 2,2h16c1.11,0 2,-0.89 2,-2L22,8c0,-1.11 -0.89,-2 -2,-2zM15,4c0.55,0 1,0.45 1,1s-0.45,1 -1,1 -1,-0.45 -1,-1 0.45,-1 1,-1zM9,4c0.55,0 1,0.45 1,1s-0.45,1 -1,1 -1,-0.45 -1,-1 0.45,-1 1,-1zM20,19L4,19v-2h16v2zM20,14L4,14L4,8h5.08L7,10.83 8.62,12 11,8.76l1,-1.36 1,1.36L15.38,12 17,10.83 14.92,8L20,8v6z\"/>\n</vector>\n"
  },
  {
    "path": "live/src/main/res/drawable/ic_forum_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24.0\"\n        android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M21,6h-2v9L6,15v2c0,0.55 0.45,1 1,1h11l4,4L22,7c0,-0.55 -0.45,-1 -1,-1zM17,12L17,3c0,-0.55 -0.45,-1 -1,-1L3,2c-0.55,0 -1,0.45 -1,1v14l4,-4h10c0.55,0 1,-0.45 1,-1z\"/>\n</vector>\n"
  },
  {
    "path": "live/src/main/res/drawable/ic_fullscreen_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24.0\"\n        android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M7,14L5,14v5h5v-2L7,17v-3zM5,10h2L7,7h3L10,5L5,5v5zM17,17h-3v2h5v-5h-2v3zM14,5v2h3v3h2L19,5h-5z\"/>\n</vector>\n"
  },
  {
    "path": "live/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillColor=\"#26A69A\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n"
  },
  {
    "path": "live/src/main/res/drawable/ic_mail_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24.0\"\n        android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M20,4L4,4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2zM20,8l-8,5 -8,-5L4,6l8,5 8,-5v2z\"/>\n</vector>\n"
  },
  {
    "path": "live/src/main/res/drawable/ic_more_vert_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24.0\"\n        android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z\"/>\n</vector>\n"
  },
  {
    "path": "live/src/main/res/drawable/ic_person_add_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24.0\"\n        android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M15,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM6,10L6,7L4,7v3L1,10v2h3v3h2v-3h3v-2L6,10zM15,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z\"/>\n</vector>\n"
  },
  {
    "path": "live/src/main/res/drawable/ic_send_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24.0\"\n        android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M2.01,21L23,12 2.01,3 2,10l15,2 -15,2z\"/>\n</vector>\n"
  },
  {
    "path": "live/src/main/res/drawable/ic_share_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24.0\"\n        android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,-2.92 -2.92,-2.92z\"/>\n</vector>\n"
  },
  {
    "path": "live/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillType=\"evenOdd\"\n        android:pathData=\"M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"78.5885\"\n                android:endY=\"90.9159\"\n                android:startX=\"48.7653\"\n                android:startY=\"61.0927\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        android:pathData=\"M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\" />\n</vector>\n"
  },
  {
    "path": "live/src/main/res/layout/activity_live.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    tools:context=\".view.live.activity.LiveActivity\">\n\n    <RelativeLayout\n        android:orientation=\"vertical\"\n        android:fitsSystemWindows=\"true\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <include android:id=\"@+id/bar_layout\" layout=\"@layout/layout_toolbar\"/>\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/rv\"\n            android:layout_below=\"@id/bar_layout\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"/>\n\n        <View android:layout_below=\"@id/bar_layout\"\n            android:background=\"@drawable/bg_toolbar_shade\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"5dp\"/>\n\n    </RelativeLayout>\n\n</layout>"
  },
  {
    "path": "live/src/main/res/layout/activity_live_room.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <FrameLayout\n        android:id=\"@+id/fragment_container\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"/>\n\n</layout>"
  },
  {
    "path": "live/src/main/res/layout/fragment_fullscreen.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\">\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:background=\"@android:color/black\">\n\n        <RelativeLayout\n            android:id=\"@+id/rl_container\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\">\n\n            <FrameLayout\n                android:id=\"@+id/rl_video\"\n                android:layout_gravity=\"center\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\">\n\n                <androidx.appcompat.widget.AppCompatImageView\n                    android:id=\"@+id/iv_cover\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"match_parent\"\n                    android:scaleType=\"centerCrop\" />\n\n                <ProgressBar\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_gravity=\"center\" />\n\n            </FrameLayout>\n\n            <RelativeLayout\n                android:id=\"@+id/rl_user\"\n                android:layout_marginTop=\"30dp\"\n                android:layout_marginStart=\"10dp\"\n                android:layout_marginBottom=\"10dp\"\n                android:orientation=\"horizontal\"\n                android:background=\"@drawable/full_room_avatar_bg\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"34dp\">\n\n                <me.shouheng.commons.view.widget.CircleImageView\n                    android:id=\"@+id/iv_avatar\"\n                    tools:src=\"@color/colorAccent\"\n                    android:layout_width=\"34dp\"\n                    android:layout_height=\"34dp\"\n                    android:layout_marginEnd=\"6dp\" />\n\n                <TextView\n                    android:id=\"@+id/tv_name\"\n                    tools:text=\"User name\"\n                    android:textSize=\"13sp\"\n                    android:textColor=\"@android:color/white\"\n                    android:layout_marginTop=\"1dp\"\n                    android:layout_toEndOf=\"@id/iv_avatar\"\n                    android:singleLine=\"true\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"/>\n\n                <TextView\n                    android:id=\"@+id/tv_follow\"\n                    tools:text=\"follow\"\n                    android:textSize=\"12sp\"\n                    android:textColor=\"@android:color/white\"\n                    android:singleLine=\"true\"\n                    android:layout_toEndOf=\"@+id/iv_avatar\"\n                    android:layout_below=\"@+id/tv_name\"\n                    android:layout_marginEnd=\"10dp\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\" />\n\n            </RelativeLayout>\n\n            <TextView\n                android:id=\"@+id/tv_account\"\n                android:layout_below=\"@+id/rl_user\"\n                tools:text=\"Account\"\n                android:textColor=\"@android:color/white\"\n                android:textSize=\"14sp\"\n                android:singleLine=\"true\"\n                android:layout_marginStart=\"10dp\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"/>\n\n            <androidx.appcompat.widget.AppCompatImageView\n                android:id=\"@+id/iv_back\"\n                android:layout_alignParentEnd=\"true\"\n                android:layout_marginTop=\"30dp\"\n                android:layout_marginEnd=\"10dp\"\n                android:padding=\"5dp\"\n                android:tint=\"@android:color/white\"\n                android:src=\"@drawable/ic_close_black_24dp\"\n                android:background=\"@drawable/full_room_avatar_bg\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"/>\n\n            <LinearLayout\n                android:id=\"@+id/ll_room\"\n                android:orientation=\"horizontal\"\n                android:layout_alignParentBottom=\"true\"\n                android:layout_margin=\"10dp\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\">\n\n                <androidx.appcompat.widget.AppCompatImageView\n                    android:id=\"@+id/iv_input\"\n                    android:padding=\"5dp\"\n                    android:clickable=\"true\"\n                    android:focusable=\"true\"\n                    android:layout_marginStart=\"10dp\"\n                    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n                    android:background=\"@drawable/full_room_avatar_bg\"\n                    android:src=\"@drawable/ic_forum_black_24dp\"\n                    android:tint=\"@android:color/white\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"/>\n\n                <androidx.appcompat.widget.AppCompatImageView\n                    android:id=\"@+id/iv_follow\"\n                    android:padding=\"5dp\"\n                    android:clickable=\"true\"\n                    android:focusable=\"true\"\n                    android:layout_marginStart=\"10dp\"\n                    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n                    android:background=\"@drawable/full_room_avatar_bg\"\n                    android:src=\"@drawable/ic_person_add_black_24dp\"\n                    android:tint=\"@android:color/white\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"/>\n\n                <View\n                    android:layout_width=\"0dp\"\n                    android:layout_height=\"0dp\"\n                    android:layout_weight=\"1\"/>\n\n                <androidx.appcompat.widget.AppCompatImageView\n                    android:id=\"@+id/iv_gift\"\n                    android:padding=\"5dp\"\n                    android:clickable=\"true\"\n                    android:focusable=\"true\"\n                    android:layout_marginStart=\"10dp\"\n                    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n                    android:background=\"@drawable/full_room_avatar_bg\"\n                    android:src=\"@drawable/ic_card_giftcard_black_24dp\"\n                    android:tint=\"@android:color/white\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"/>\n\n                <androidx.appcompat.widget.AppCompatImageView\n                    android:id=\"@+id/iv_share\"\n                    android:padding=\"5dp\"\n                    android:clickable=\"true\"\n                    android:focusable=\"true\"\n                    android:layout_marginStart=\"10dp\"\n                    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n                    android:background=\"@drawable/full_room_avatar_bg\"\n                    android:src=\"@drawable/ic_send_black_24dp\"\n                    android:tint=\"@android:color/white\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"/>\n\n                <androidx.appcompat.widget.AppCompatImageView\n                    android:id=\"@+id/iv_message\"\n                    android:padding=\"5dp\"\n                    android:clickable=\"true\"\n                    android:focusable=\"true\"\n                    android:layout_marginStart=\"10dp\"\n                    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n                    android:background=\"@drawable/full_room_avatar_bg\"\n                    android:src=\"@drawable/ic_mail_black_24dp\"\n                    android:tint=\"@android:color/white\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"/>\n\n            </LinearLayout>\n\n        </RelativeLayout>\n\n        <me.shouheng.live.common.widget.FlutteringLayout\n            android:id=\"@+id/ftl\"\n            android:layout_alignParentEnd=\"true\"\n            android:layout_alignParentBottom=\"true\"\n            android:layout_width=\"150dp\"\n            android:layout_height=\"250dp\"/>\n\n    </RelativeLayout>\n\n</layout>"
  },
  {
    "path": "live/src/main/res/layout/fragment_room.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\">\n\n    <LinearLayout\n        android:orientation=\"vertical\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <RelativeLayout\n            android:id=\"@+id/rl_container\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"200dp\"\n            android:background=\"@android:color/black\">\n\n            <FrameLayout\n                android:id=\"@+id/rl_video\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                android:layout_gravity=\"center\">\n\n                <ProgressBar\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_gravity=\"center\" />\n\n            </FrameLayout>\n\n            <androidx.appcompat.widget.AppCompatImageView\n                android:id=\"@+id/iv_back\"\n                android:layout_margin=\"10dp\"\n                android:src=\"@drawable/ic_arrow_back_black_24dp\"\n                android:tint=\"@android:color/white\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\" />\n\n            <androidx.appcompat.widget.AppCompatImageView\n                android:id=\"@+id/iv_more\"\n                android:layout_alignParentEnd=\"true\"\n                android:tint=\"@android:color/white\"\n                android:layout_margin=\"10dp\"\n                android:src=\"@drawable/ic_more_vert_black_24dp\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\" />\n\n            <androidx.appcompat.widget.AppCompatImageView\n                android:id=\"@+id/iv_share\"\n                android:layout_toStartOf=\"@id/iv_more\"\n                android:tint=\"@android:color/white\"\n                android:layout_marginTop=\"10dp\"\n                android:src=\"@drawable/ic_share_black_24dp\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\" />\n\n            <RelativeLayout\n                android:id=\"@+id/rl_room_info\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\">\n\n                <TextView\n                    android:id=\"@+id/tv_room_title\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:maxLines=\"1\"\n                    android:singleLine=\"true\"/>\n\n                <androidx.appcompat.widget.AppCompatImageView\n                    android:id=\"@+id/iv_full_screen\"\n                    android:layout_alignParentEnd=\"true\"\n                    android:layout_alignParentBottom=\"true\"\n                    android:layout_margin=\"10dp\"\n                    android:tint=\"@android:color/white\"\n                    android:src=\"@drawable/ic_fullscreen_black_24dp\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"/>\n\n            </RelativeLayout>\n\n        </RelativeLayout>\n\n        <LinearLayout\n            android:orientation=\"vertical\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\">\n\n            <TextView\n                android:id=\"@+id/tv_title\"\n                tools:text=\"This is the fucking test title for a lot numbers of rows\"\n                android:textColor=\"@android:color/black\"\n                android:layout_marginStart=\"20dp\"\n                android:layout_marginEnd=\"20dp\"\n                android:layout_marginTop=\"20dp\"\n                android:textSize=\"18sp\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\" />\n\n            <TextView\n                android:id=\"@+id/tv_views\"\n                android:textSize=\"12sp\"\n                tools:text=\"239 views\"\n                android:layout_marginTop=\"8dp\"\n                android:layout_marginBottom=\"8dp\"\n                android:layout_marginStart=\"20dp\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\" />\n\n            <TextView\n                android:id=\"@+id/tv_anno\"\n                tools:text=\"直播时间，上午9点到下午3点。\"\n                android:layout_marginStart=\"20dp\"\n                android:layout_marginEnd=\"20dp\"\n                android:layout_marginBottom=\"10dp\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\" />\n\n            <View android:background=\"#ccc\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"1px\"/>\n\n            <LinearLayout\n                android:id=\"@+id/ll_user\"\n                android:background=\"?attr/selectableItemBackground\"\n                android:clickable=\"true\"\n                android:focusable=\"true\"\n                android:paddingStart=\"20dp\"\n                android:paddingEnd=\"20dp\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\">\n\n                <me.shouheng.commons.view.widget.CircleImageView\n                    android:id=\"@+id/iv_avatar\"\n                    tools:src=\"@color/accent\"\n                    android:layout_marginTop=\"10dp\"\n                    android:layout_width=\"50dp\"\n                    android:layout_height=\"50dp\" />\n\n                <LinearLayout\n                    android:orientation=\"vertical\"\n                    android:gravity=\"center_vertical\"\n                    android:layout_marginStart=\"10dp\"\n                    android:layout_marginTop=\"10dp\"\n                    android:layout_marginBottom=\"10dp\"\n                    android:layout_weight=\"1\"\n                    android:layout_width=\"0dp\"\n                    android:layout_height=\"wrap_content\">\n\n                    <TextView\n                        android:id=\"@+id/tv_user_name\"\n                        tools:text=\"浏阳河长的像猴子\"\n                        android:textSize=\"16sp\"\n                        android:textColor=\"@android:color/black\"\n                        android:layout_width=\"match_parent\"\n                        android:layout_height=\"wrap_content\" />\n\n                    <TextView\n                        android:id=\"@+id/tv_follow\"\n                        android:textSize=\"12sp\"\n                        tools:text=\"239 views\"\n                        android:layout_marginTop=\"5dp\"\n                        android:layout_marginBottom=\"5dp\"\n                        android:layout_width=\"wrap_content\"\n                        android:layout_height=\"wrap_content\" />\n\n                    <TextView\n                        android:id=\"@+id/tv_user_intro\"\n                        tools:text=\"保持善良 \\n宽容，不忘初心。\"\n                        android:layout_width=\"match_parent\"\n                        android:layout_height=\"wrap_content\" />\n\n                </LinearLayout>\n\n                <TextView\n                    android:clickable=\"true\"\n                    android:focusable=\"true\"\n                    android:background=\"?attr/selectableItemBackgroundBorderless\"\n                    android:layout_marginTop=\"10dp\"\n                    android:text=\"@string/live_subscribe\"\n                    android:textSize=\"16sp\"\n                    android:textColor=\"@android:color/holo_red_light\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\" />\n\n            </LinearLayout>\n\n            <View android:background=\"#ccc\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"1px\"/>\n\n        </LinearLayout>\n\n    </LinearLayout>\n\n</layout>"
  },
  {
    "path": "live/src/main/res/layout/fragment_video.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\" >\n\n    <LinearLayout\n        android:orientation=\"vertical\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <com.pili.pldroid.player.widget.PLVideoTextureView\n            android:id=\"@+id/vtv\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:layout_gravity=\"center\" />\n\n    </LinearLayout>\n\n</layout>"
  },
  {
    "path": "live/src/main/res/layout/item_remmend.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:orientation=\"vertical\"\n    android:layout_marginBottom=\"6dp\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\">\n\n    <LinearLayout\n        android:orientation=\"horizontal\"\n        android:gravity=\"center_vertical\"\n        android:padding=\"8dp\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\">\n\n        <androidx.appcompat.widget.AppCompatImageView\n            android:id=\"@+id/iv_category\"\n            tools:src=\"@color/colorPrimary\"\n            android:layout_marginEnd=\"4dp\"\n            android:layout_width=\"15dp\"\n            android:layout_height=\"15dp\"/>\n\n        <TextView\n            android:id=\"@+id/tv_category\"\n            android:textSize=\"14sp\"\n            tools:text=\"Category name\"\n            android:singleLine=\"true\"\n            android:layout_weight=\"1\"\n            android:layout_width=\"0dp\"\n            android:layout_height=\"wrap_content\" />\n\n        <TextView\n            android:id=\"@+id/tv_more\"\n            android:text=\"@string/live_recommend_more\"\n            android:textSize=\"12sp\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\" />\n\n    </LinearLayout>\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:id=\"@+id/rv\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\" />\n\n</LinearLayout>"
  },
  {
    "path": "live/src/main/res/layout/item_remmend_child.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.cardview.widget.CardView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:orientation=\"vertical\"\n    app:cardElevation=\"2dp\"\n    app:cardCornerRadius=\"0.5dp\"\n    android:layout_margin=\"4dp\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\">\n\n    <RelativeLayout\n        android:orientation=\"vertical\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\">\n\n        <androidx.appcompat.widget.AppCompatImageView\n            android:id=\"@+id/iv\"\n            android:scaleType=\"centerCrop\"\n            android:src=\"@drawable/live_default\"\n            tools:src=\"@color/colorPrimary\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"100dp\"/>\n\n        <TextView\n            android:id=\"@+id/tv_status\"\n            android:text=\"@string/live_living\"\n            android:textColor=\"@android:color/white\"\n            android:maxLines=\"1\"\n            android:textSize=\"12sp\"\n            android:visibility=\"gone\"\n            android:layout_marginEnd=\"2dp\"\n            android:layout_alignParentEnd=\"true\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"/>\n\n        <TextView\n            android:id=\"@+id/tv_title\"\n            tools:text=\"Title\"\n            android:textSize=\"12sp\"\n            android:textColor=\"@android:color/white\"\n            android:singleLine=\"true\"\n            android:layout_alignBottom=\"@+id/iv\"\n            android:layout_margin=\"2dp\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"/>\n\n        <LinearLayout\n            android:id=\"@+id/ll\"\n            android:layout_below=\"@+id/iv\"\n            android:gravity=\"center_horizontal\"\n            android:padding=\"6dp\"\n            android:orientation=\"horizontal\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\">\n\n            <TextView\n                android:id=\"@+id/tv_name\"\n                android:textSize=\"12sp\"\n                tools:text=\"Name\"\n                android:layout_weight=\"3\"\n                android:layout_gravity=\"center_vertical\"\n                android:singleLine=\"true\"\n                android:layout_width=\"0dp\"\n                android:layout_height=\"wrap_content\"/>\n\n            <androidx.appcompat.widget.AppCompatImageView\n                android:src=\"@drawable/viewer\"\n                android:layout_gravity=\"center_vertical\"\n                android:layout_marginEnd=\"10dp\"\n                android:layout_width=\"10dp\"\n                android:layout_height=\"10dp\" />\n\n            <TextView\n                android:id=\"@+id/tv_viewer\"\n                tools:text=\"Viewer\"\n                android:textSize=\"12sp\"\n                android:gravity=\"center_vertical\"\n                android:textColor=\"@android:color/darker_gray\"\n                android:singleLine=\"true\"\n                android:layout_weight=\"1.2\"\n                android:layout_width=\"0dp\"\n                android:layout_height=\"wrap_content\"/>\n\n        </LinearLayout>\n\n    </RelativeLayout>\n\n</androidx.cardview.widget.CardView>"
  },
  {
    "path": "live/src/main/res/layout/layout_banner.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\">\n\n    <com.bigkoo.convenientbanner.ConvenientBanner\n        android:id=\"@+id/cb\"\n        android:minHeight=\"100dp\"\n        android:layout_marginBottom=\"6dp\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"100dp\"\n        app:canLoop=\"true\"/>\n\n</LinearLayout>\n"
  },
  {
    "path": "live/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "live/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "live/src/main/res/values/attrs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <declare-styleable name=\"FlutteringLayout\">\n        <attr format=\"integer\" name=\"enter_duration\"/>\n        <attr format=\"integer\" name=\"duration\"/>\n        <attr format=\"float\" name=\"scale\"/>\n        <attr format=\"boolean\" name=\"same_size\"/>\n    </declare-styleable>\n</resources>"
  },
  {
    "path": "live/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n</resources>\n"
  },
  {
    "path": "live/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">live</string>\n</resources>\n"
  },
  {
    "path": "live/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.NoActionBar\">\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "live/src/test/java/me/shouheng/live/ExampleUnitTest.java",
    "content": "package me.shouheng.live;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() {\n        assertEquals(4, 2 + 2);\n    }\n}"
  }
]