[
  {
    "path": ".gitignore",
    "content": ".DS_Store\n.dart_tool/\n\n.packages\n.pub/\n\nbuild/\n"
  },
  {
    "path": ".idea/codeStyles/Project.xml",
    "content": "<component name=\"ProjectCodeStyleConfiguration\">\n  <code_scheme name=\"Project\" version=\"173\">\n    <codeStyleSettings language=\"XML\">\n      <indentOptions>\n        <option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\" />\n      </indentOptions>\n      <arrangement>\n        <rules>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>xmlns:android</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>xmlns:.*</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n              <order>BY_NAME</order>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*:id</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*:name</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>name</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>style</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n              <order>BY_NAME</order>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n                </AND>\n              </match>\n              <order>ANDROID_ATTRIBUTE_ORDER</order>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>.*</XML_NAMESPACE>\n                </AND>\n              </match>\n              <order>BY_NAME</order>\n            </rule>\n          </section>\n        </rules>\n      </arrangement>\n    </codeStyleSettings>\n  </code_scheme>\n</component>"
  },
  {
    "path": ".idea/kotlinc.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"Kotlin2JvmCompilerArguments\">\n    <option name=\"jvmTarget\" value=\"1.8\" />\n  </component>\n</project>"
  },
  {
    "path": ".idea/libraries/Dart_SDK.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Dart SDK\">\n    <CLASSES>\n      <root url=\"file:///usr/local/flutter/bin/cache/dart-sdk/lib/async\" />\n      <root url=\"file:///usr/local/flutter/bin/cache/dart-sdk/lib/collection\" />\n      <root url=\"file:///usr/local/flutter/bin/cache/dart-sdk/lib/convert\" />\n      <root url=\"file:///usr/local/flutter/bin/cache/dart-sdk/lib/core\" />\n      <root url=\"file:///usr/local/flutter/bin/cache/dart-sdk/lib/developer\" />\n      <root url=\"file:///usr/local/flutter/bin/cache/dart-sdk/lib/html\" />\n      <root url=\"file:///usr/local/flutter/bin/cache/dart-sdk/lib/io\" />\n      <root url=\"file:///usr/local/flutter/bin/cache/dart-sdk/lib/isolate\" />\n      <root url=\"file:///usr/local/flutter/bin/cache/dart-sdk/lib/math\" />\n      <root url=\"file:///usr/local/flutter/bin/cache/dart-sdk/lib/mirrors\" />\n      <root url=\"file:///usr/local/flutter/bin/cache/dart-sdk/lib/typed_data\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES />\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Flutter_Plugins.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Flutter Plugins\" type=\"FlutterPluginsLibraryType\">\n    <CLASSES>\n      <root url=\"file://$PROJECT_DIR$\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES />\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/KotlinJavaRuntime.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"KotlinJavaRuntime\">\n    <CLASSES>\n      <root url=\"jar://$PROJECT_DIR$/lib/kotlin-stdlib.jar!/\" />\n      <root url=\"jar://$PROJECT_DIR$/lib/kotlin-reflect.jar!/\" />\n      <root url=\"jar://$PROJECT_DIR$/lib/kotlin-test.jar!/\" />\n      <root url=\"jar://$PROJECT_DIR$/lib/kotlin-stdlib-jdk7.jar!/\" />\n      <root url=\"jar://$PROJECT_DIR$/lib/kotlin-stdlib-jdk8.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$PROJECT_DIR$/lib/kotlin-stdlib-sources.jar!/\" />\n      <root url=\"jar://$PROJECT_DIR$/lib/kotlin-reflect-sources.jar!/\" />\n      <root url=\"jar://$PROJECT_DIR$/lib/kotlin-test-sources.jar!/\" />\n      <root url=\"jar://$PROJECT_DIR$/lib/kotlin-stdlib-jdk7-sources.jar!/\" />\n      <root url=\"jar://$PROJECT_DIR$/lib/kotlin-stdlib-jdk8-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/modules.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectModuleManager\">\n    <modules>\n      <module fileurl=\"file://$PROJECT_DIR$/floaty_head.iml\" filepath=\"$PROJECT_DIR$/floaty_head.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/android/floaty_head_android.iml\" filepath=\"$PROJECT_DIR$/android/floaty_head_android.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/example/android/floaty_head_example_android.iml\" filepath=\"$PROJECT_DIR$/example/android/floaty_head_example_android.iml\" />\n    </modules>\n  </component>\n</project>\n"
  },
  {
    "path": ".idea/runConfigurations/example_lib_main_dart.xml",
    "content": "<component name=\"ProjectRunConfigurationManager\">\n  <configuration default=\"false\" name=\"example/lib/main.dart\" type=\"FlutterRunConfigurationType\" factoryName=\"Flutter\">\n    <option name=\"filePath\" value=\"$PROJECT_DIR$/example/lib/main.dart\" />\n    <method />\n  </configuration>\n</component>"
  },
  {
    "path": ".idea/workspace.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ChangeListManager\">\n    <list default=\"true\" id=\"2dcf5f1d-20d8-41af-b667-14e6b22c5dda\" name=\"Default Changelist\" comment=\"\" />\n    <option name=\"SHOW_DIALOG\" value=\"false\" />\n    <option name=\"HIGHLIGHT_CONFLICTS\" value=\"true\" />\n    <option name=\"HIGHLIGHT_NON_ACTIVE_CHANGELIST\" value=\"false\" />\n    <option name=\"LAST_RESOLUTION\" value=\"IGNORE\" />\n  </component>\n  <component name=\"ExecutionTargetManager\" SELECTED_TARGET=\"27abde15dc217ece\" />\n  <component name=\"FileTemplateManagerImpl\">\n    <option name=\"RECENT_TEMPLATES\">\n      <list>\n        <option value=\"Kotlin Class\" />\n      </list>\n    </option>\n  </component>\n  <component name=\"ProjectId\" id=\"1ghpx5JiqLL4CNwOkv4sxh7sTZq\" />\n  <component name=\"ProjectViewState\">\n    <option name=\"hideEmptyMiddlePackages\" value=\"true\" />\n    <option name=\"showExcludedFiles\" value=\"true\" />\n    <option name=\"showLibraryContents\" value=\"true\" />\n  </component>\n  <component name=\"PropertiesComponent\">\n    <property name=\"dart.analysis.tool.window.force.activate\" value=\"false\" />\n    <property name=\"last_opened_file_path\" value=\"$PROJECT_DIR$\" />\n    <property name=\"show.migrate.to.gradle.popup\" value=\"false\" />\n  </component>\n  <component name=\"RecentsManager\">\n    <key name=\"CopyFile.RECENT_KEYS\">\n      <recent name=\"$PROJECT_DIR$/android/src/main/kotlin/ni/devotion/floaty_head\" />\n    </key>\n  </component>\n  <component name=\"SvnConfiguration\">\n    <configuration />\n  </component>\n  <component name=\"TaskManager\">\n    <task active=\"true\" id=\"Default\" summary=\"Default task\">\n      <changelist id=\"2dcf5f1d-20d8-41af-b667-14e6b22c5dda\" name=\"Default Changelist\" comment=\"\" />\n      <created>1598576921664</created>\n      <option name=\"number\" value=\"Default\" />\n      <option name=\"presentableId\" value=\"Default\" />\n      <updated>1598576921664</updated>\n    </task>\n    <servers />\n  </component>\n  <component name=\"WindowStateProjectService\">\n    <state x=\"743\" y=\"285\" width=\"428\" height=\"486\" key=\"FileChooserDialogImpl\" timestamp=\"1598579852080\">\n      <screen x=\"0\" y=\"0\" width=\"1920\" height=\"1053\" />\n    </state>\n    <state x=\"743\" y=\"285\" width=\"428\" height=\"486\" key=\"FileChooserDialogImpl/0.0.1920.1053@0.0.1920.1053\" timestamp=\"1598579852080\" />\n  </component>\n</project>"
  },
  {
    "path": ".metadata",
    "content": "# This file tracks properties of this Flutter project.\n# Used by Flutter tool to assess capabilities and perform upgrades etc.\n#\n# This file should be version controlled and should not be manually edited.\n\nversion:\n  revision: 216dee60c0cc9449f0b29bcf922974d612263e24\n  channel: stable\n\nproject_type: plugin\n"
  },
  {
    "path": ".vscode/launch.json",
    "content": "{\n    // Use IntelliSense to learn about possible attributes.\n    // Hover to view descriptions of existing attributes.\n    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387\n    \"version\": \"0.2.0\",\n    \"configurations\": [\n        {\n            \"name\": \"Flutter\",\n            \"program\": \"lib/main.dart\",\n            \"request\": \"launch\",\n            \"type\": \"dart\"\n        }\n    ]\n}"
  },
  {
    "path": "CHANGELOG.md",
    "content": "## [2.0.0-nullsafety.0] - 2021.03.06\n* mirgrate to nullsafety\n## [1.1.0] - 2020.09.19\n* Added documentation.\n* Refactored all the code.\n* Added independent functionality chathead works even if the app is killed.\n## [1.0.0] - 2020.09.05\n\n* Initial Release\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to Floaty_Chathead\n\n:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:\n\nThe following is a set of guidelines for contributing to Floaty_Chathead. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request.\n\n## How Can I Contribute?\n\n### Reporting Bugs\n\n> **Note:** If you find a **Closed** issue that seems like it is the same thing that you're experiencing, open a new issue and include a link to the original issue in the body of your new one.\n\n#### How Do I Submit A (Good) Bug Report?\n\nBugs are tracked as [GitHub issues](https://guides.github.com/features/issues/). After you've determined [which repository](#atom-and-packages) your bug is related to, create an issue on that repository and provide the following information by filling in [the template](https://github.com/atom/.github/blob/master/.github/ISSUE_TEMPLATE/bug_report.md).\n\nExplain the problem and include additional details to help maintainers reproduce the problem:\n\n* **Use a clear and descriptive title** for the issue to identify the problem.\n* **Describe the exact steps which reproduce the problem** in as many details as possible. For example, start by explaining how the plugin was intended to work on your app, e.g. which command exactly you used in the terminal. When listing steps, **don't just say what you did, but explain how you did it**.\n* **Provide specific examples to demonstrate the steps**. Include links to files or GitHub projects, or copy/pasteable snippets, which you use in those examples. If you're providing snippets in the issue, use [Markdown code blocks](https://help.github.com/articles/markdown-basics/#multiple-lines).\n* **Describe the behavior you observed after following the steps** and point out what exactly is the problem with that behavior.\n* **Explain which behavior you expected to see instead and why.**\n* **Include screenshots and animated GIFs** which show you following the described steps and clearly demonstrate the problem. If you use the keyboard while following the steps, **record the GIF with the [Keybinding Resolver](https://github.com/atom/keybinding-resolver) shown**. You can use [this tool](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux.\n* **If you're reporting that Floaty_Chathead crashed**, include a crash report with a stack trace from the project console. Include the crash report in the issue in a [code block](https://help.github.com/articles/markdown-basics/#multiple-lines), a [file attachment](https://help.github.com/articles/file-attachments-on-issues-and-pull-requests/), or put it in a [gist](https://gist.github.com/) and provide link to that gist.\n* **If the problem wasn't triggered by a specific action**, describe what you were doing before the problem happened and share more information using the guidelines below.\n\n### Suggesting Enhancements\n\nThis section guides you through submitting an enhancement suggestion for Floaty_Chathead, including completely new features and minor improvements to existing functionality. Following these guidelines helps maintainers and the flutter community understand your suggestion :pencil: and find related suggestions :mag_right:.\n\nBefore creating enhancement suggestions, please check [this list](#before-submitting-an-enhancement-suggestion) as you might find out that you don't need to create one. When you are creating an enhancement suggestion, please [include as many details as possible](#how-do-i-submit-a-good-enhancement-suggestion). Fill in [the template](https://github.com/atom/.github/blob/master/.github/ISSUE_TEMPLATE/feature_request.md), including the steps that you imagine you would take if the feature you're requesting existed.\n\n#### How Do I Submit A (Good) Enhancement Suggestion?\n\nEnhancement suggestions are tracked as [GitHub issues](https://guides.github.com/features/issues/). After you've determined [which repository](#atom-and-packages) your enhancement suggestion is related to, create an issue on that repository and provide the following information:\n\n* **Use a clear and descriptive title** for the issue to identify the suggestion.\n* **Provide a step-by-step description of the suggested enhancement** in as many details as possible.\n* **Provide specific examples to demonstrate the steps**. Include copy/pasteable snippets which you use in those examples, as [Markdown code blocks](https://help.github.com/articles/markdown-basics/#multiple-lines).\n* **Describe the current behavior** and **explain which behavior you expected to see instead** and why.\n* **Include screenshots and animated GIFs** which help you demonstrate the steps or point out the part of Atom which the suggestion is related to. You can use [this tool](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux.\n* **Explain why this enhancement would be useful** to most Flutter users.\n\n### Pull Requests\n\nThe process described here has several goals:\n\n- Fix problems that are important to user\n\n[search-atom-repo-label-enhancement]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Aenhancement\n[search-atom-org-label-enhancement]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Aenhancement\n[search-atom-repo-label-bug]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Abug\n[search-atom-org-label-bug]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Abug\n[search-atom-repo-label-question]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Aquestion\n[search-atom-org-label-question]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Aquestion\n[search-atom-repo-label-feedback]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Afeedback\n[search-atom-org-label-feedback]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Afeedback\n[search-atom-repo-label-help-wanted]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Ahelp-wanted\n[search-atom-org-label-help-wanted]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Ahelp-wanted\n[search-atom-repo-label-beginner]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Abeginner\n[search-atom-org-label-beginner]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Abeginner\n[search-atom-repo-label-more-information-needed]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Amore-information-needed\n[search-atom-org-label-more-information-needed]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Amore-information-needed\n[search-atom-repo-label-needs-reproduction]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Aneeds-reproduction\n[search-atom-org-label-needs-reproduction]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Aneeds-reproduction\n[search-atom-repo-label-triage-help-needed]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Atriage-help-needed\n[search-atom-org-label-triage-help-needed]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Atriage-help-needed\n[search-atom-repo-label-windows]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Awindows\n[search-atom-org-label-windows]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Awindows\n[search-atom-repo-label-linux]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Alinux\n[search-atom-org-label-linux]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Alinux\n[search-atom-repo-label-mac]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Amac\n[search-atom-org-label-mac]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Amac\n[search-atom-repo-label-documentation]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Adocumentation\n[search-atom-org-label-documentation]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Adocumentation\n[search-atom-repo-label-performance]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Aperformance\n[search-atom-org-label-performance]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Aperformance\n[search-atom-repo-label-security]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Asecurity\n[search-atom-org-label-security]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Asecurity\n[search-atom-repo-label-ui]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Aui\n[search-atom-org-label-ui]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Aui\n[search-atom-repo-label-api]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Aapi\n[search-atom-org-label-api]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Aapi\n[search-atom-repo-label-crash]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Acrash\n[search-atom-org-label-crash]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Acrash\n[search-atom-repo-label-auto-indent]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Aauto-indent\n[search-atom-org-label-auto-indent]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Aauto-indent\n[search-atom-repo-label-encoding]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Aencoding\n[search-atom-org-label-encoding]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Aencoding\n[search-atom-repo-label-network]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Anetwork\n[search-atom-org-label-network]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Anetwork\n[search-atom-repo-label-uncaught-exception]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Auncaught-exception\n[search-atom-org-label-uncaught-exception]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Auncaught-exception\n[search-atom-repo-label-git]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Agit\n[search-atom-org-label-git]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Agit\n[search-atom-repo-label-blocked]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Ablocked\n[search-atom-org-label-blocked]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Ablocked\n[search-atom-repo-label-duplicate]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Aduplicate\n[search-atom-org-label-duplicate]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Aduplicate\n[search-atom-repo-label-wontfix]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Awontfix\n[search-atom-org-label-wontfix]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Awontfix\n[search-atom-repo-label-invalid]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Ainvalid\n[search-atom-org-label-invalid]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Ainvalid\n[search-atom-repo-label-package-idea]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Apackage-idea\n[search-atom-org-label-package-idea]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Apackage-idea\n[search-atom-repo-label-wrong-repo]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Awrong-repo\n[search-atom-org-label-wrong-repo]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Awrong-repo\n[search-atom-repo-label-editor-rendering]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Aeditor-rendering\n[search-atom-org-label-editor-rendering]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Aeditor-rendering\n[search-atom-repo-label-build-error]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Abuild-error\n[search-atom-org-label-build-error]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Abuild-error\n[search-atom-repo-label-error-from-pathwatcher]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Aerror-from-pathwatcher\n[search-atom-org-label-error-from-pathwatcher]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Aerror-from-pathwatcher\n[search-atom-repo-label-error-from-save]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Aerror-from-save\n[search-atom-org-label-error-from-save]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Aerror-from-save\n[search-atom-repo-label-error-from-open]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Aerror-from-open\n[search-atom-org-label-error-from-open]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Aerror-from-open\n[search-atom-repo-label-installer]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Ainstaller\n[search-atom-org-label-installer]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Ainstaller\n[search-atom-repo-label-auto-updater]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Aauto-updater\n[search-atom-org-label-auto-updater]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Aauto-updater\n[search-atom-repo-label-deprecation-help]: https://github.com/search?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Adeprecation-help\n[search-atom-org-label-deprecation-help]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Adeprecation-help\n[search-atom-repo-label-electron]: https://github.com/search?q=is%3Aissue+repo%3Aatom%2Fatom+is%3Aopen+label%3Aelectron\n[search-atom-org-label-electron]: https://github.com/search?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Aelectron\n[search-atom-repo-label-work-in-progress]: https://github.com/search?q=is%3Aopen+is%3Apr+repo%3Aatom%2Fatom+label%3Awork-in-progress\n[search-atom-org-label-work-in-progress]: https://github.com/search?q=is%3Aopen+is%3Apr+user%3Aatom+label%3Awork-in-progress\n[search-atom-repo-label-needs-review]: https://github.com/search?q=is%3Aopen+is%3Apr+repo%3Aatom%2Fatom+label%3Aneeds-review\n[search-atom-org-label-needs-review]: https://github.com/search?q=is%3Aopen+is%3Apr+user%3Aatom+label%3Aneeds-review\n[search-atom-repo-label-under-review]: https://github.com/search?q=is%3Aopen+is%3Apr+repo%3Aatom%2Fatom+label%3Aunder-review\n[search-atom-org-label-under-review]: https://github.com/search?q=is%3Aopen+is%3Apr+user%3Aatom+label%3Aunder-review\n[search-atom-repo-label-requires-changes]: https://github.com/search?q=is%3Aopen+is%3Apr+repo%3Aatom%2Fatom+label%3Arequires-changes\n[search-atom-org-label-requires-changes]: https://github.com/search?q=is%3Aopen+is%3Apr+user%3Aatom+label%3Arequires-changes\n[search-atom-repo-label-needs-testing]: https://github.com/search?q=is%3Aopen+is%3Apr+repo%3Aatom%2Fatom+label%3Aneeds-testing\n[search-atom-org-label-needs-testing]: https://github.com/search?q=is%3Aopen+is%3Apr+user%3Aatom+label%3Aneeds-testing\n\n[beginner]:https://github.com/search?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue+label%3Abeginner+label%3Ahelp-wanted+user%3Aatom+sort%3Acomments-desc\n[help-wanted]:https://github.com/search?q=is%3Aopen+is%3Aissue+label%3Ahelp-wanted+user%3Aatom+sort%3Acomments-desc+-label%3Abeginner\n[contributing-to-official-atom-packages]:https://flight-manual.atom.io/hacking-atom/sections/contributing-to-official-atom-packages/\n[hacking-on-atom-core]: https://flight-manual.atom.io/hacking-atom/sections/hacking-on-atom-core/\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2020 Luis Cardoza Bird\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
  },
  {
    "path": "README.md",
    "content": "# Floaty Chathead (Deprecated)\n\n[![Deprecated](https://img.shields.io/badge/status-deprecated-red.svg)](https://pub.dev/packages/floaty_chatheads)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n\n> **This package has been deprecated.** Please use [`floaty_chatheads`](https://pub.dev/packages/floaty_chatheads) instead.\n\n---\n\n## Migration\n\nReplace your dependency:\n\n```yaml\n# Before\ndependencies:\n  floaty_chathead: ^3.0.0\n\n# After\ndependencies:\n  floaty_chatheads: ^1.0.0\n```\n\nThen run:\n\n```bash\nflutter pub get\n```\n\n## What changed?\n\n`floaty_chatheads` is a full rewrite of `floaty_chathead` using a **federated plugin architecture**, bringing:\n\n- **iOS support** alongside Android\n- **Type-safe platform channels** via Pigeon (no more manual `MethodChannel` strings)\n- **Typed messaging** with `FloatyMessenger<T>` for serialized communication between main app and overlay\n- **Lifecycle-aware controller** (`FloatyController`) with `ChangeNotifier` integration\n- **Widget-level integration** via `FloatyScope` (InheritedWidget) and `FloatyPermissionGate`\n- **Multi-chathead management** (`addChatHead`, `removeChatHead`, `expandChatHead`, `collapseChatHead`)\n- **Built-in UI components** (`FloatyMiniPlayer`, `FloatyNotificationCard`)\n- **100% test coverage** on handwritten code with 132 tests\n- **Testing utilities** (`FakeFloatyPlatform`, `FakeOverlayDataSource`) for easy widget testing\n\n## Links\n\n- [`floaty_chatheads` on pub.dev](https://pub.dev/packages/floaty_chatheads)\n- [`floaty_chatheads` repository](https://github.com/Crdzbird/floaty_chatheads)\n\n---\n\n## License\n\nThis project is licensed under the MIT License. See [LICENSE](LICENSE) for details.\n"
  },
  {
    "path": "android/.gitignore",
    "content": "*.iml\n.gradle\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n.DS_Store\n/build\n/captures\n"
  },
  {
    "path": "android/.idea/.name",
    "content": "floaty_head"
  },
  {
    "path": "android/.idea/assetWizardSettings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"WizardSettings\">\n    <option name=\"children\">\n      <map>\n        <entry key=\"vectorWizard\">\n          <value>\n            <PersistentState>\n              <option name=\"children\">\n                <map>\n                  <entry key=\"vectorAssetStep\">\n                    <value>\n                      <PersistentState>\n                        <option name=\"values\">\n                          <map>\n                            <entry key=\"assetSourceType\" value=\"FILE\" />\n                            <entry key=\"outputName\" value=\"ic_chathead\" />\n                            <entry key=\"sourceFile\" value=\"$USER_HOME$/Pictures/burbuja-de-dialogo.svg\" />\n                          </map>\n                        </option>\n                      </PersistentState>\n                    </value>\n                  </entry>\n                </map>\n              </option>\n            </PersistentState>\n          </value>\n        </entry>\n      </map>\n    </option>\n  </component>\n</project>"
  },
  {
    "path": "android/.idea/codeStyles/Project.xml",
    "content": "<component name=\"ProjectCodeStyleConfiguration\">\n  <code_scheme name=\"Project\" version=\"173\">\n    <JetCodeStyleSettings>\n      <option name=\"PACKAGES_TO_USE_STAR_IMPORTS\">\n        <value>\n          <package name=\"java.util\" alias=\"false\" withSubpackages=\"false\" />\n          <package name=\"kotlinx.android.synthetic\" alias=\"false\" withSubpackages=\"true\" />\n          <package name=\"io.ktor\" alias=\"false\" withSubpackages=\"true\" />\n        </value>\n      </option>\n      <option name=\"PACKAGES_IMPORT_LAYOUT\">\n        <value>\n          <package name=\"\" alias=\"false\" withSubpackages=\"true\" />\n          <package name=\"java\" alias=\"false\" withSubpackages=\"true\" />\n          <package name=\"javax\" alias=\"false\" withSubpackages=\"true\" />\n          <package name=\"kotlin\" alias=\"false\" withSubpackages=\"true\" />\n          <package name=\"\" alias=\"true\" withSubpackages=\"true\" />\n        </value>\n      </option>\n    </JetCodeStyleSettings>\n    <codeStyleSettings language=\"XML\">\n      <indentOptions>\n        <option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\" />\n      </indentOptions>\n      <arrangement>\n        <rules>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>xmlns:android</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>xmlns:.*</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n              <order>BY_NAME</order>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*:id</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*:name</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>name</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>style</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n              <order>BY_NAME</order>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n                </AND>\n              </match>\n              <order>ANDROID_ATTRIBUTE_ORDER</order>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>.*</XML_NAMESPACE>\n                </AND>\n              </match>\n              <order>BY_NAME</order>\n            </rule>\n          </section>\n        </rules>\n      </arrangement>\n    </codeStyleSettings>\n  </code_scheme>\n</component>"
  },
  {
    "path": "android/.idea/gradle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"GradleMigrationSettings\" migrationVersion=\"1\" />\n  <component name=\"GradleSettings\">\n    <option name=\"linkedExternalProjectsSettings\">\n      <GradleProjectSettings>\n        <option name=\"testRunner\" value=\"PLATFORM\" />\n        <option name=\"distributionType\" value=\"DEFAULT_WRAPPED\" />\n        <option name=\"externalProjectPath\" value=\"$PROJECT_DIR$\" />\n        <option name=\"gradleJvm\" value=\"1.8\" />\n        <option name=\"modules\">\n          <set>\n            <option value=\"$PROJECT_DIR$\" />\n          </set>\n        </option>\n        <option name=\"resolveModulePerSourceSet\" value=\"false\" />\n      </GradleProjectSettings>\n    </option>\n  </component>\n</project>"
  },
  {
    "path": "android/.idea/jarRepositories.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"RemoteRepositoriesConfiguration\">\n    <remote-repository>\n      <option name=\"id\" value=\"central\" />\n      <option name=\"name\" value=\"Maven Central repository\" />\n      <option name=\"url\" value=\"https://repo1.maven.org/maven2\" />\n    </remote-repository>\n    <remote-repository>\n      <option name=\"id\" value=\"jboss.community\" />\n      <option name=\"name\" value=\"JBoss Community repository\" />\n      <option name=\"url\" value=\"https://repository.jboss.org/nexus/content/repositories/public/\" />\n    </remote-repository>\n    <remote-repository>\n      <option name=\"id\" value=\"BintrayJCenter\" />\n      <option name=\"name\" value=\"BintrayJCenter\" />\n      <option name=\"url\" value=\"https://jcenter.bintray.com/\" />\n    </remote-repository>\n    <remote-repository>\n      <option name=\"id\" value=\"Google\" />\n      <option name=\"name\" value=\"Google\" />\n      <option name=\"url\" value=\"https://dl.google.com/dl/android/maven2/\" />\n    </remote-repository>\n  </component>\n</project>"
  },
  {
    "path": "android/.idea/misc.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectRootManager\" version=\"2\" languageLevel=\"JDK_1_8\" project-jdk-name=\"1.8\" project-jdk-type=\"JavaSDK\">\n    <output url=\"file://$PROJECT_DIR$/build/classes\" />\n  </component>\n  <component name=\"ProjectType\">\n    <option name=\"id\" value=\"Android\" />\n  </component>\n</project>"
  },
  {
    "path": "android/.idea/modules.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectModuleManager\">\n    <modules>\n      <module fileurl=\"file://$PROJECT_DIR$/.idea/modules/floaty_head.iml\" filepath=\"$PROJECT_DIR$/.idea/modules/floaty_head.iml\" group=\"floaty_head\" />\n    </modules>\n  </component>\n</project>"
  },
  {
    "path": "android/.idea/runConfigurations.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"RunConfigurationProducerService\">\n    <option name=\"ignoredProducers\">\n      <set>\n        <option value=\"org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer\" />\n        <option value=\"org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer\" />\n        <option value=\"org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer\" />\n      </set>\n    </option>\n  </component>\n</project>"
  },
  {
    "path": "android/.idea/vcs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"VcsDirectoryMappings\">\n    <mapping directory=\"$PROJECT_DIR$/..\" vcs=\"Git\" />\n  </component>\n</project>"
  },
  {
    "path": "android/build.gradle",
    "content": "group 'ni.devotion.floaty_head'\nversion '1.0-SNAPSHOT'\n\nbuildscript {\n    ext.kotlin_version = '1.4.0'\n    repositories {\n        google()\n        jcenter()\n    }\n\n    dependencies {\n        classpath 'com.android.tools.build:gradle:4.0.1'\n        classpath \"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version\"\n    }\n}\n\nrootProject.allprojects {\n    repositories {\n        google()\n        jcenter()\n    }\n}\n\napply plugin: 'com.android.library'\napply plugin: 'kotlin-android'\n\nandroid {\n    compileSdkVersion 30\n    defaultConfig {\n        minSdkVersion 16\n        targetSdkVersion 30\n    }\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n    lintOptions {\n        disable 'InvalidPackage'\n    }\n}\n\ndependencies {\n    implementation \"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version\"\n    implementation 'androidx.constraintlayout:constraintlayout:2.0.1'\n    implementation 'com.google.android.material:material:1.2.0'\n    implementation 'androidx.appcompat:appcompat:1.2.0'\n    implementation 'com.facebook.rebound:rebound:0.3.8'\n    implementation 'androidx.core:core-ktx:1.3.1'\n    implementation 'androidx.legacy:legacy-support-v4:1.0.0'\n}\n"
  },
  {
    "path": "android/gradle/wrapper/gradle-wrapper.properties",
    "content": "#Thu Aug 27 19:59:47 CST 2020\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-6.1.1-all.zip\n"
  },
  {
    "path": "android/gradle.properties",
    "content": "org.gradle.jvmargs=-Xmx1536M\nandroid.useAndroidX=true\nandroid.enableJetifier=true\nandroid.enableR8=true\n"
  },
  {
    "path": "android/gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\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\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\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\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\nesac\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\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\" ] ; 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# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "android/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windowz variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\nif \"%@eval[2+2]\" == \"4\" goto 4NT_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\ngoto execute\r\n\r\n:4NT_args\r\n@rem Get arguments from the 4NT Shell from JP Software\r\nset CMD_LINE_ARGS=%$\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\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%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "android/settings.gradle",
    "content": "rootProject.name = 'floaty_head'\n"
  },
  {
    "path": "android/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n  package=\"ni.devotion.floaty_head\">\n\n    <uses-permission android:name=\"android.permission.FOREGROUND_SERVICE\" />\n    <uses-permission android:name=\"android.permission.WAKE_LOCK\" />\n    <uses-permission android:name=\"android.permission.SYSTEM_ALERT_WINDOW\" />\n\n    <application>\n        <activity\n            android:name=\".MainActivity\"\n            android:allowEmbedded=\"true\"\n            android:documentLaunchMode=\"always\"\n            android:label=\"floaty_head\"\n            android:resizeableActivity=\"true\"\n            android:showOnLockScreen=\"true\"\n            android:theme=\"@style/AppTheme.NoActionBar\"\n            tools:targetApi=\"n\" />\n        <service\n            android:name=\".services.FloatyIconService\"\n            android:enabled=\"true\"\n            android:exported=\"true\"\n            android:permission=\"android.permission.FOREGROUND_SERVICE\"/>\n        <service\n            android:name=\".services.FloatyContentJobService\"\n            android:enabled=\"true\"\n            android:exported=\"false\"\n            android:permission=\"android.permission.BIND_JOB_SERVICE\"/>\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "android/src/main/java/ni/devotion/floaty_head/FloatFragment.kt",
    "content": "package ni.devotion.floaty_head\n\nimport android.content.Context\nimport android.view.View\nimport android.view.animation.AlphaAnimation\nimport android.view.animation.Animation\nimport android.widget.FrameLayout\nimport android.widget.LinearLayout\nimport com.facebook.rebound.SimpleSpringListener\nimport com.facebook.rebound.Spring\nimport com.facebook.rebound.SpringSystem\nimport ni.devotion.floaty_head.floating_chathead.SpringConfigs\nimport ni.devotion.floaty_head.R\nimport ni.devotion.floaty_head.utils.Managment.bodyView\nimport ni.devotion.floaty_head.utils.Managment.footerView\nimport ni.devotion.floaty_head.utils.Managment.headerView\n\n\nclass FloatFragment(context: Context) : LinearLayout(context) {\n    private val springSystem = SpringSystem.create()\n    private val scaleSpring = springSystem.createSpring()\n    private lateinit var content: LinearLayout\n\n    init {\n        setupView()\n    }\n\n    private fun setupView() {\n        context.setTheme(R.style.Theme_MaterialComponents_Light)\n        inflate(context, R.layout.fragment_float, this)\n        scaleSpring.addListener(object : SimpleSpringListener() {\n            override fun onSpringUpdate(spring: Spring) {\n                scaleX = spring.currentValue.toFloat()\n                scaleY = spring.currentValue.toFloat()\n            }\n        })\n        scaleSpring.springConfig = SpringConfigs.CONTENT_SCALE\n        scaleSpring.currentValue = 0.0\n        content = findViewById<LinearLayout>(R.id.contentLayout)\n        headerView?.let {\n            content.addView(it)\n        }\n        bodyView?.let {\n            content.addView(it)\n        }\n        footerView?.let {\n            content.addView(it)\n        }\n    }\n\n    override fun onViewRemoved(child: View?) {\n        super.onViewRemoved(child)\n        content.removeAllViews()\n    }\n\n    fun hideContent() {\n        scaleSpring.endValue = 0.0\n        val anim = AlphaAnimation(1.0f, 0.0f)\n        anim.duration = 200\n        anim.repeatMode = Animation.RELATIVE_TO_SELF\n        startAnimation(anim)\n    }\n\n    fun showContent() {\n        scaleSpring.endValue = 1.0\n        val anim = AlphaAnimation(0.0f, 1.0f)\n        anim.duration = 100\n        anim.repeatMode = Animation.RELATIVE_TO_SELF\n        startAnimation(anim)\n    }\n}"
  },
  {
    "path": "android/src/main/kotlin/ni/devotion/floaty_head/FloatyHeadPlugin.kt",
    "content": "package ni.devotion.floaty_head\n\nimport android.app.Activity\nimport android.content.ComponentName\nimport android.content.Context\nimport android.content.Intent\nimport android.content.ServiceConnection\nimport android.graphics.BitmapFactory\nimport android.net.Uri\nimport android.os.Build\nimport android.os.IBinder\nimport android.provider.Settings\nimport android.util.Log\nimport android.widget.FrameLayout\nimport androidx.annotation.NonNull\nimport io.flutter.embedding.engine.loader.FlutterLoader\nimport io.flutter.embedding.engine.plugins.FlutterPlugin\nimport io.flutter.embedding.engine.plugins.activity.ActivityAware\nimport io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding\nimport io.flutter.plugin.common.MethodCall\nimport io.flutter.plugin.common.MethodChannel\nimport io.flutter.plugin.common.MethodChannel.MethodCallHandler\nimport io.flutter.plugin.common.MethodChannel.Result\nimport io.flutter.plugin.common.PluginRegistry\nimport io.flutter.plugin.common.PluginRegistry.Registrar\nimport io.flutter.view.FlutterCallbackInformation\nimport io.flutter.view.FlutterMain\nimport io.flutter.view.FlutterNativeView\nimport io.flutter.view.FlutterRunArguments\nimport ni.devotion.floaty_head.services.FloatyContentJobService.Companion.INTENT_EXTRA_IS_UPDATE_WINDOW\nimport ni.devotion.floaty_head.services.FloatyIconService\nimport ni.devotion.floaty_head.services.FloatyContentJobService\nimport ni.devotion.floaty_head.utils.Commons.getMapFromObject\nimport ni.devotion.floaty_head.utils.Constants.SHARED_PREF_FLOATY_HEAD\nimport ni.devotion.floaty_head.utils.Constants.CALLBACK_HANDLE_KEY\nimport ni.devotion.floaty_head.utils.Constants.CODE_CALLBACK_HANDLE_KEY\nimport ni.devotion.floaty_head.utils.Constants.BACKGROUND_CHANNEL\nimport ni.devotion.floaty_head.utils.Constants.INTENT_EXTRA_PARAMS_MAP\nimport ni.devotion.floaty_head.utils.Constants.METHOD_CHANNEL\nimport ni.devotion.floaty_head.utils.Constants.KEY_BODY\nimport ni.devotion.floaty_head.utils.Constants.KEY_FOOTER\nimport ni.devotion.floaty_head.utils.Constants.KEY_HEADER\nimport ni.devotion.floaty_head.utils.Managment\nimport ni.devotion.floaty_head.utils.Managment.bodyMap\nimport ni.devotion.floaty_head.utils.Managment.bodyView\nimport ni.devotion.floaty_head.utils.Managment.footerMap\nimport ni.devotion.floaty_head.utils.Managment.footerView\nimport ni.devotion.floaty_head.utils.Managment.headerView\nimport ni.devotion.floaty_head.utils.Managment.headersMap\nimport ni.devotion.floaty_head.utils.Managment.layoutParams\nimport ni.devotion.floaty_head.utils.Managment.sIsIsolateRunning\nimport ni.devotion.floaty_head.views.BodyView\nimport ni.devotion.floaty_head.views.FooterView\nimport ni.devotion.floaty_head.views.HeaderView\nimport java.io.IOException\nimport java.util.ArrayList\nimport java.util.HashMap\nimport kotlin.collections.List\nimport kotlin.collections.Map\n\nclass FloatyHeadPlugin : ActivityAware, FlutterPlugin, MethodChannel.MethodCallHandler {\n    companion object {\n        var mBound: Boolean = false\n        lateinit var instance: FloatyHeadPlugin\n        var activity: Activity? = null\n        var context: Context? = null\n        var sBackgroundFlutterView: FlutterNativeView? = null\n        private var channel: MethodChannel? = null\n        private var backgroundChannel: MethodChannel? = null\n    }\n    var sPluginRegistrantCallback: PluginRegistry.PluginRegistrantCallback? = null\n    private val CODE_DRAW_OVER_OTHER_APP_PERMISSION = 2084\n\n    fun setPluginRegistrant(callback: PluginRegistry.PluginRegistrantCallback) {\n        Managment.pluginRegistrantC = callback\n        sPluginRegistrantCallback = callback\n    }\n\n    fun registerWith(pluginRegistrar: Registrar) {\n        context = pluginRegistrar.context()\n        channel = MethodChannel(pluginRegistrar.messenger(), METHOD_CHANNEL)\n        channel?.setMethodCallHandler(FloatyHeadPlugin())\n    }\n\n    fun startCallBackHandler(context: Context) {\n        var preferences = context.getSharedPreferences(SHARED_PREF_FLOATY_HEAD, 0)\n        val callBackHandle: Long = preferences.getLong(CALLBACK_HANDLE_KEY, -1)\n        if (callBackHandle != -1L) {\n            FlutterMain.ensureInitializationComplete(context, null)\n            val mAppBundlePath: String = FlutterMain.findAppBundlePath()\n            val flutterCallback: FlutterCallbackInformation = FlutterCallbackInformation.lookupCallbackInformation(callBackHandle)\n            sBackgroundFlutterView?.let { sbfv ->\n                backgroundChannel ?: run {\n                    backgroundChannel = MethodChannel(sbfv, BACKGROUND_CHANNEL)\n                }\n                Managment.sIsIsolateRunning.set(true)\n            } ?: run {\n                sBackgroundFlutterView = FlutterNativeView(context, true)\n                if(mAppBundlePath != null && !Managment.sIsIsolateRunning.get()) {\n                    Managment.pluginRegistrantC ?: run {\n                        Log.i(\"TAG\", \"Unable to start callBackHandle... as plugin is not registered\")\n                        return\n                    }\n                    val args = FlutterRunArguments()\n                    args.bundlePath = mAppBundlePath\n                    args.entrypoint = flutterCallback.callbackName\n                    args.libraryPath = flutterCallback.callbackLibraryPath\n                    sBackgroundFlutterView!!.runFromBundle(args)\n                    Managment.pluginRegistrantC?.registerWith(sBackgroundFlutterView!!.getPluginRegistry())\n                    backgroundChannel = MethodChannel(sBackgroundFlutterView!!, BACKGROUND_CHANNEL)\n                    Managment.sIsIsolateRunning.set(true)\n                }\n                Managment.sIsIsolateRunning.set(true)\n            }\n        }\n    }\n\n    fun invokeCallBack(context: Context, type: String, params: Any) {\n        val argumentsList: MutableList<Any> = ArrayList()\n        val preferences = activity!!.applicationContext.getSharedPreferences(SHARED_PREF_FLOATY_HEAD, 0)\n        val codeCallBackHandle = preferences.getLong(CODE_CALLBACK_HANDLE_KEY, -1)\n        if (codeCallBackHandle == -1L) {\n            Log.e(\"TAG\", \"Back failed, as codeCallBackHandle is null\")\n        } else {\n            argumentsList.clear()\n            argumentsList.add(codeCallBackHandle)\n            argumentsList.add(type)\n            argumentsList.add(params)\n            if(Managment.sIsIsolateRunning.get()) {\n                backgroundChannel ?: run{\n                    backgroundChannel = MethodChannel(sBackgroundFlutterView, BACKGROUND_CHANNEL)\n                }\n                try {\n                    val retries = intArrayOf(2)\n                    invokeCallBackToFlutter(backgroundChannel!!, \"callBack\", argumentsList, retries)\n                    //channel!!.invokeMethod(\"callBack\", argumentsList);\n                }catch (ex: Exception) {\n                    Log.e(\"TAG\", \"Exception in invoking callback $ex\")\n                }\n            } else {\n                Log.e(\"TAG\", \"invokeCallBack failed, as isolate is not running\")\n            }\n        }\n    }\n\n    private fun invokeCallBackToFlutter(channel: MethodChannel, method: String, arguments: List<Any>, retries: IntArray) {\n        channel.invokeMethod(method, arguments, object : MethodChannel.Result {\n            override fun success(o: Any?) {\n                Log.i(\"TAG\", \"Invoke call back success\")\n            }\n\n            override fun error(s: String?, s1: String?, o: Any?) {\n                Log.e(\"TAG\", \"Error $s$s1\")\n            }\n\n            override fun notImplemented() {\n                if (retries[0] > 0) {\n                    Log.d(\"TAG\", \"Not Implemented method $method. Trying again to check if it works\")\n                    invokeCallBackToFlutter(channel, method, arguments, retries)\n                } else {\n                    Log.e(\"TAG\", \"Not Implemented method $method\")\n                }\n                retries[0]--\n            }\n        })\n    }\n\n    private fun FloatyHeadPlugin(_context: Context, _activity: Activity, _methodChannel: MethodChannel) {\n        activity = _activity\n        context = _context\n        channel = _methodChannel\n        channel?.let { it.setMethodCallHandler(this) }\n    }\n\n    override fun onMethodCall(call: MethodCall, @NonNull result: Result) {\n        when (call.method) {\n            \"start\" -> {\n                Managment.globalContext = activity?.applicationContext\n                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(activity)) {\n                    val packageName = activity?.packageName\n                    activity?.startActivityForResult(\n                            Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse(\"package:$packageName\")),\n                            CODE_DRAW_OVER_OTHER_APP_PERMISSION)\n                } else {\n                    if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {\n                        val subIntent = Intent(activity?.applicationContext, FloatyContentJobService::class.java)\n                        subIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\n                        subIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)\n                        subIntent.putExtra(INTENT_EXTRA_IS_UPDATE_WINDOW, true)\n                        activity?.startService(subIntent)\n                        mBound = true\n                    } else {\n                        val subIntent = Intent(activity?.applicationContext, FloatyContentJobService::class.java)\n                        activity?.startForegroundService(subIntent)\n                        mBound = true\n                    }\n                }\n            }\n            \"isOpen\" -> result.success(mBound)\n            \"close\" -> {\n                if(mBound){\n                    FloatyContentJobService.instance!!.closeWindow(true)\n                    if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q){\n                        activity?.stopService(Intent(activity?.applicationContext, FloatyContentJobService::class.java))\n                    }else{\n                        activity?.startForegroundService(Intent(activity?.applicationContext, FloatyContentJobService::class.java))\n                    }\n                    mBound = false\n                }\n            }\n            \"setIcon\" -> result.success(setIconFromAsset(call.arguments as String))\n            \"setBackgroundCloseIcon\" -> result.success(setBackgroundCloseIconFromAsset(call.arguments as String))\n            \"setCloseIcon\" -> result.success(setCloseIconFromAsset(call.arguments as String))\n            \"setNotificationTitle\" -> result.success(setNotificationTitle(call.arguments as String))\n            \"setNotificationIcon\" -> result.success(setNotificationIcon(call.arguments as String))\n            \"setFloatyHeadContent\" -> {\n                assert((call.arguments != null))\n                val updateParams = call.arguments as HashMap<String, Any>\n                headersMap = getMapFromObject(updateParams, KEY_HEADER)\n                bodyMap = getMapFromObject(updateParams, KEY_BODY)\n                footerMap = getMapFromObject(updateParams, KEY_FOOTER)\n                layoutParams = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT)\n                try {\n                    headersMap?.let {\n                        headerView = HeaderView(activity!!.applicationContext, it).view\n                    }\n                    bodyMap?.let {\n                        bodyView = BodyView(activity!!.applicationContext, it).view\n                    }\n                    footerMap?.let {\n                        footerView = FooterView(activity!!.applicationContext, it).view\n                    }\n                } catch (except: Exception) {\n                    except.printStackTrace()\n                }\n                result.success(true)\n            }\n            \"registerCallBackHandler\" -> {\n                try {\n                    val arguments = call.arguments as List<*>\n                    arguments ?: result.success(false)\n                    arguments?.let {\n                        val callBackHandle = (it[0]).toString().toLong()\n                        val onClickHandle = (it[1]).toString().toLong()\n                        val preferences = activity?.applicationContext!!.getSharedPreferences(SHARED_PREF_FLOATY_HEAD, 0)\n                        preferences?.edit()?.putLong(CALLBACK_HANDLE_KEY, callBackHandle)!!.commit()\n                        preferences?.edit()?.putLong(CODE_CALLBACK_HANDLE_KEY, onClickHandle)!!.commit()\n                        startCallBackHandler(activity!!.applicationContext)\n                        result.success(true)\n                    }\n                } catch (ex: Exception) {\n                    Log.e(\"TAG\", \"Exception in registerOnClickHandler \" + ex.toString())\n                    result.success(false)\n                }\n            }\n            else -> result.notImplemented()\n        }\n    }\n\n    private fun setNotificationTitle(title: String):Int {\n        var result = -1\n        try {\n            Managment.notificationTitle = title\n            result = 1\n        }catch (e: IOException) {\n            e.printStackTrace()\n        }\n        return result\n    }\n\n    private fun setNotificationIcon(assetPath: String):Int {\n        var result = -1\n        try {\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {\n                val inputStream = activity!!.applicationContext.assets.open(\"flutter_assets/\" + assetPath)\n                val bitmap = BitmapFactory.decodeStream(inputStream)\n                Managment.notificationIcon = bitmap\n                result = 1\n            } else {\n                val assetLookupKey = FlutterLoader.getInstance().getLookupKeyForAsset(assetPath)\n                val assetManager = activity!!.applicationContext.assets\n                val assetFileDescriptor = assetManager.openFd(assetLookupKey)\n                val inputStream = assetFileDescriptor.createInputStream()\n                Managment.notificationIcon = BitmapFactory.decodeStream(inputStream)\n                result = 1\n            }\n        }catch (e: IOException) {\n            e.printStackTrace()\n        }\n        return result\n    }\n\n    private fun setBackgroundCloseIconFromAsset(assetPath: String):Int {\n        var result = -1\n        try {\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {\n                val inputStream = activity!!.applicationContext.assets.open(\"flutter_assets/\" + assetPath)\n                val bitmap = BitmapFactory.decodeStream(inputStream)\n                Managment.backgroundCloseIcon = bitmap\n                result = 1\n            }\n            else {\n                val assetLookupKey = FlutterLoader.getInstance().getLookupKeyForAsset(assetPath)\n                val assetManager = activity!!.applicationContext.assets\n                val assetFileDescriptor = assetManager.openFd(assetLookupKey)\n                val inputStream = assetFileDescriptor.createInputStream()\n                Managment.backgroundCloseIcon = BitmapFactory.decodeStream(inputStream)\n                result = 1\n            }\n        }catch (e: IOException) {\n            e.printStackTrace()\n        }\n        return result\n    }\n\n    private fun setCloseIconFromAsset(assetPath: String):Int {\n        var result = -1\n        try {\n            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){\n                val inputStream = activity!!.applicationContext.assets.open(\"flutter_assets/\" + assetPath)\n                val bitmap = BitmapFactory.decodeStream(inputStream)\n                Managment.closeIcon = bitmap\n                result = 1\n            }\n            else {\n                val assetLookupKey = FlutterLoader.getInstance().getLookupKeyForAsset(assetPath)\n                val assetManager = activity!!.applicationContext.assets\n                val assetFileDescriptor = assetManager.openFd(assetLookupKey)\n                val inputStream = assetFileDescriptor.createInputStream()\n                Managment.closeIcon = BitmapFactory.decodeStream(inputStream)\n                result = 1\n            }\n        }catch (e: IOException) {\n            e.printStackTrace()\n        }\n        return result\n    }\n\n    private fun setIconFromAsset(assetPath: String):Int {\n        var result = -1\n        try {\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {\n                val inputStream = activity!!.applicationContext.assets.open(\"flutter_assets/\" + assetPath)\n                val bitmap = BitmapFactory.decodeStream(inputStream)\n                Managment.floatingIcon = bitmap\n                result = 1\n            }\n            else {\n                val assetLookupKey = FlutterLoader.getInstance().getLookupKeyForAsset(assetPath)\n                val assetManager = activity!!.applicationContext.assets\n                val assetFileDescriptor = assetManager.openFd(assetLookupKey)\n                val inputStream = assetFileDescriptor.createInputStream()\n                Managment.floatingIcon = BitmapFactory.decodeStream(inputStream)\n                result = 1\n            }\n        }catch (e: IOException) {\n            e.printStackTrace()\n        }\n        return result\n    }\n\n    override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {\n        channel?.setMethodCallHandler(null)\n        //release()\n    }\n\n  override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {\n      channel = MethodChannel(flutterPluginBinding.binaryMessenger, METHOD_CHANNEL)\n      channel?.setMethodCallHandler(this)\n  }\n\n  override fun onAttachedToActivity(binding: ActivityPluginBinding) {\n      activity = binding.activity\n      Managment.activity = binding.activity\n      instance = this@FloatyHeadPlugin\n  }\n\n  override fun onDetachedFromActivity() {\n      //release()\n  }\n\n  override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {\n      activity = binding.activity\n      Managment.activity = binding.activity\n      instance = this@FloatyHeadPlugin\n  }\n\n  override fun onDetachedFromActivityForConfigChanges() {\n      //release()\n  }\n}\n"
  },
  {
    "path": "android/src/main/kotlin/ni/devotion/floaty_head/MainActivity.kt",
    "content": "package ni.devotion.floaty_head\n\nimport android.content.Context\nimport android.graphics.Color\nimport android.os.Bundle\nimport android.widget.FrameLayout\nimport android.widget.LinearLayout\nimport androidx.appcompat.app.AppCompatActivity\nimport ni.devotion.floaty_head.utils.Commons.getMapFromObject\nimport ni.devotion.floaty_head.utils.Constants.INTENT_EXTRA_PARAMS_MAP\nimport ni.devotion.floaty_head.utils.Constants.KEY_BODY\nimport ni.devotion.floaty_head.utils.Constants.KEY_FOOTER\nimport ni.devotion.floaty_head.utils.Constants.KEY_HEADER\nimport ni.devotion.floaty_head.utils.Managment.bodyMap\nimport ni.devotion.floaty_head.utils.Managment.footerMap\nimport ni.devotion.floaty_head.utils.Managment.headerView\nimport ni.devotion.floaty_head.utils.Managment.headersMap\nimport ni.devotion.floaty_head.utils.Managment.layoutParams\nimport ni.devotion.floaty_head.utils.Managment.paramsMap\nimport ni.devotion.floaty_head.views.HeaderView\nimport java.util.*\n\nclass MainActivity : AppCompatActivity() {\n  override fun onCreate(savedInstanceState: Bundle?) {\n      super.onCreate(savedInstanceState)\n  }\n}"
  },
  {
    "path": "android/src/main/kotlin/ni/devotion/floaty_head/floating_chathead/ChatHead.kt",
    "content": "package ni.devotion.floaty_head.floating_chathead\n\nimport android.graphics.*\nimport android.graphics.BitmapFactory.*\nimport android.view.*\nimport com.facebook.rebound.*\nimport ni.devotion.floaty_head.R\nimport ni.devotion.floaty_head.services.FloatyIconService\nimport ni.devotion.floaty_head.utils.ImageHelper\nimport ni.devotion.floaty_head.utils.Managment\nimport kotlin.math.hypot\nimport kotlin.math.pow\n\nclass ChatHead(var chatHeads: ChatHeads): View(chatHeads.context), View.OnTouchListener, SpringListener {\n    var isTop: Boolean = false\n    var isActive: Boolean = false\n\n    var params: WindowManager.LayoutParams = WindowManager.LayoutParams(\n        WindowManager.LayoutParams.WRAP_CONTENT,\n        WindowManager.LayoutParams.WRAP_CONTENT,\n            WindowManagerHelper.getLayoutFlag(),\n        0,\n        PixelFormat.TRANSLUCENT\n    )\n    var springSystem = SpringSystem.create()\n    var springX = springSystem.createSpring()\n    var springY = springSystem.createSpring()\n    val paint = Paint()\n    private var initialX = 0.0f\n    private var initialY = 0.0f\n    private var initialTouchX = 0.0f\n    private var initialTouchY = 0.0f\n    private var moving = false\n    override fun onSpringEndStateChange(spring: Spring?) {}\n\n    override fun onSpringAtRest(spring: Spring?) {}\n\n    override fun onSpringActivate(spring: Spring?) {}\n\n    init {\n        params.gravity = Gravity.TOP or Gravity.START\n        params.x = 0\n        params.y = 0\n        params.width = ChatHeads.CHAT_HEAD_SIZE + 15\n        params.height = ChatHeads.CHAT_HEAD_SIZE + 30\n        springX.addListener(object : SimpleSpringListener() {\n            override fun onSpringUpdate(spring: Spring) {\n                x = spring.currentValue.toFloat()\n            }\n        })\n        springX.springConfig = SpringConfigs.NOT_DRAGGING\n        springX.addListener(this)\n        springY.addListener(object : SimpleSpringListener() {\n            override fun onSpringUpdate(spring: Spring) {\n                y = spring.currentValue.toFloat()\n            }\n        })\n        springY.springConfig = SpringConfigs.NOT_DRAGGING\n        springY.addListener(this)\n        this.setLayerType(LAYER_TYPE_HARDWARE, paint)\n        chatHeads.addView(this, params)\n        this.setOnTouchListener(this)\n    }\n\n    override fun onSpringUpdate(spring: Spring) {\n        if (spring !== this.springX && spring !== this.springY) return\n        val totalVelocity = hypot(springX.velocity, springY.velocity).toInt()\n        chatHeads.onSpringUpdate(this, spring, totalVelocity)\n    }\n\n    override fun onDraw(canvas: Canvas?) {\n        Managment.floatingIcon ?: canvas?.drawBitmap(ImageHelper.addShadow((ImageHelper.getCircularBitmap(decodeResource(Managment.globalContext!!.resources, R.drawable.bot)))), 0f, 0f, paint)\n        Managment.floatingIcon?.let {\n            canvas?.drawBitmap(ImageHelper.addShadow(ImageHelper.getCircularBitmap(it)), 0f, 0f, paint)\n        }\n    }\n\n    override fun onTouch(v: View?, event: MotionEvent?): Boolean {\n        val currentChatHead = chatHeads.chatHeads.find { it == v }!!\n        val metrics = WindowManagerHelper.getScreenSize()\n        when (event!!.action) {\n            MotionEvent.ACTION_DOWN -> {\n                initialX = x\n                initialY = y\n                initialTouchX = event.rawX\n                initialTouchY = event.rawY\n                scaleX = 0.9f\n                scaleY = 0.9f\n            }\n            MotionEvent.ACTION_UP -> {\n                if (!moving) {\n                    if (currentChatHead.isActive) {\n                        chatHeads.collapse()\n                    } else {\n                        val selectedChatHead = chatHeads.chatHeads.find { it.isActive }\n                        selectedChatHead?.isActive = false\n                        currentChatHead.isActive = true\n                        chatHeads.changeContent()\n                    }\n                } else {\n                    springX.endValue = metrics.widthPixels - width - (chatHeads.chatHeads.size - 1 - chatHeads.chatHeads.indexOf(this)) * (width + ChatHeads.CHAT_HEAD_EXPANDED_PADDING).toDouble()\n                    springY.endValue = ChatHeads.CHAT_HEAD_EXPANDED_MARGIN_TOP.toDouble()\n                    if (isActive) {\n                        chatHeads.content.showContent()\n                    }\n                }\n                scaleX = 1f\n                scaleY = 1f\n                moving = false\n            }\n            MotionEvent.ACTION_MOVE -> {\n                if (ChatHeads.distance(initialTouchX, event.rawX, initialTouchY, event.rawY) > ChatHeads.CHAT_HEAD_DRAG_TOLERANCE.pow(2) && !moving) {\n                    moving = true\n                    if (isActive) {\n                        chatHeads.content.hideContent()\n                    }\n                }\n                if (moving) {\n                    springX.currentValue = initialX + (event.rawX - initialTouchX).toDouble()\n                    springY.currentValue = initialY + (event.rawY - initialTouchY).toDouble()\n                }\n            }\n        }\n        return true\n    }\n}"
  },
  {
    "path": "android/src/main/kotlin/ni/devotion/floaty_head/floating_chathead/ChatHeads.kt",
    "content": "package ni.devotion.floaty_head.floating_chathead\n\nimport android.annotation.SuppressLint\nimport android.content.Context\nimport android.graphics.PixelFormat\nimport android.view.*\nimport android.widget.FrameLayout\nimport android.widget.LinearLayout\nimport android.view.VelocityTracker\nimport com.facebook.rebound.Spring\nimport com.facebook.rebound.SimpleSpringListener\nimport com.facebook.rebound.SpringChain\nimport java.util.*\nimport kotlin.math.*\nimport android.app.ActivityManager\nimport ni.devotion.floaty_head.FloatFragment\nimport ni.devotion.floaty_head.R\nimport ni.devotion.floaty_head.services.FloatyContentJobService\nimport ni.devotion.floaty_head.services.FloatyIconService\nimport ni.devotion.floaty_head.utils.Managment\n\n\nclass ChatHeads(context: Context) : View.OnTouchListener, FrameLayout(context) {\n    companion object {\n        val CHAT_HEAD_OUT_OF_SCREEN_X: Int = WindowManagerHelper.dpToPx(10f)\n        val CHAT_HEAD_SIZE: Int = WindowManagerHelper.dpToPx(64f)\n        val CHAT_HEAD_PADDING: Int = WindowManagerHelper.dpToPx(6f)\n        val CHAT_HEAD_EXPANDED_PADDING: Int = WindowManagerHelper.dpToPx(4f)\n        val CHAT_HEAD_EXPANDED_MARGIN_TOP: Float = WindowManagerHelper.dpToPx(4f).toFloat()\n        val CLOSE_SIZE = WindowManagerHelper.dpToPx(64f)\n        val CLOSE_CAPTURE_DISTANCE = WindowManagerHelper.dpToPx(100f)\n        val CLOSE_ADDITIONAL_SIZE = WindowManagerHelper.dpToPx(24f)\n        const val CHAT_HEAD_DRAG_TOLERANCE: Float = 20f\n        fun distance(x1: Float, x2: Float, y1: Float, y2: Float): Float {\n            return ((x1 - x2).pow(2) + (y1-y2).pow(2))\n        }\n    }\n    var wasMoving = false\n    var captured = false\n    var movingOutOfClose = false\n    private var initialX = 0.0f\n    private var initialY = 0.0f\n    private var initialTouchX = 0.0f\n    private var initialTouchY = 0.0f\n    private var initialVelocityX = 0.0\n    private var initialVelocityY = 0.0\n    private var lastY = 0.0\n    private var moving = false\n    private var toggled = false\n    private var motionTrackerUpdated = false\n    private var collapsing = false\n    private var blockAnim = false\n    private var horizontalSpringChain: SpringChain? = null\n    private var verticalSpringChain: SpringChain? = null\n    private var isOnRight = false\n    private var velocityTracker: VelocityTracker? = null\n    private var motionTracker = LinearLayout(context)\n    var topChatHead: ChatHead? = null\n    var content = FloatFragment(context)\n    private var close = Close(this)\n    var chatHeads = ArrayList<ChatHead>()\n\n    private var motionTrackerParams = WindowManager.LayoutParams(\n        CHAT_HEAD_SIZE,\n        CHAT_HEAD_SIZE + 16,\n            WindowManagerHelper.getLayoutFlag(),\n        WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS or WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,\n        PixelFormat.TRANSLUCENT\n    )\n\n    private var params = WindowManager.LayoutParams(\n        WindowManager.LayoutParams.MATCH_PARENT,\n        WindowManager.LayoutParams.MATCH_PARENT,\n            WindowManagerHelper.getLayoutFlag(),\n        WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS or WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,\n        PixelFormat.TRANSLUCENT\n    )\n\n    init {\n        context.setTheme(R.style.Theme_MaterialComponents_Light)\n        params.gravity = Gravity.START or Gravity.TOP\n        params.dimAmount = 0.7f\n        motionTrackerParams.gravity = Gravity.START or Gravity.TOP\n        FloatyContentJobService.instance?.windowManager?.addView(motionTracker, motionTrackerParams)\n        FloatyContentJobService.instance?.windowManager?.addView(this, params)\n        this.addView(content)\n        motionTracker.setOnTouchListener(this)\n        this.setOnTouchListener{ v, event ->\n            v.performClick()\n            when (event.action) {\n                MotionEvent.ACTION_UP -> {\n                    if (v == this) {\n                        collapse()\n                    }\n                }\n\n            }\n            return@setOnTouchListener false\n        }\n    }\n\n    fun setTop(chatHead: ChatHead) {\n        topChatHead?.isTop = false\n        chatHead.isTop = true\n        topChatHead = chatHead\n    }\n\n    fun fixPositions(animation: Boolean = true) {\n        if (topChatHead == null) return\n        val metrics = WindowManagerHelper.getScreenSize()\n        val newX =  if (isOnRight) metrics.widthPixels - topChatHead!!.width + CHAT_HEAD_OUT_OF_SCREEN_X.toDouble() else -CHAT_HEAD_OUT_OF_SCREEN_X.toDouble()\n        val newY = initialY.toDouble()\n        if (animation) {\n            topChatHead!!.springX.endValue = newX\n            topChatHead!!.springY.endValue = newY\n        } else {\n            topChatHead!!.springX.currentValue = newX\n            topChatHead!!.springY.currentValue = newY\n        }\n    }\n\n    private fun destroySpringChains() {\n        horizontalSpringChain?.let {\n            for (spring in it.allSprings) {\n                spring.destroy()\n            }\n        }\n        verticalSpringChain?.let {\n            for (spring in it.allSprings) {\n                spring.destroy()\n            }\n        }\n        verticalSpringChain = null\n        horizontalSpringChain = null\n    }\n\n    @SuppressLint(\"NewApi\")\n    private fun resetSpringChains() {\n       destroySpringChains()\n        horizontalSpringChain = SpringChain.create(0, 0, 200, 15)\n        verticalSpringChain = SpringChain.create(0, 0, 200, 15)\n        chatHeads.forEachIndexed { index, element ->\n            element.z = index.toFloat()\n            if (element.isTop) {\n                horizontalSpringChain!!.addSpring(object : SimpleSpringListener() { })\n                verticalSpringChain!!.addSpring(object : SimpleSpringListener() { })\n\n                element.z = chatHeads.size.toFloat()\n                horizontalSpringChain!!.setControlSpringIndex(index)\n                verticalSpringChain!!.setControlSpringIndex(index)\n            } else {\n                horizontalSpringChain!!.addSpring(object : SimpleSpringListener() {\n                    override fun onSpringUpdate(spring: Spring?) {\n                        if (!toggled && !blockAnim) {\n                            if (collapsing) {\n                                element.springX.endValue = spring!!.endValue + (chatHeads.size - 1 - index) * CHAT_HEAD_PADDING * if (isOnRight) 1 else -1\n                            } else {\n                                element.springX.currentValue = spring!!.currentValue + (chatHeads.size - 1 - index) * CHAT_HEAD_PADDING * if (isOnRight) 1 else -1\n                            }\n                        }\n                    }\n                })\n                verticalSpringChain!!.addSpring(object : SimpleSpringListener() {\n                    override fun onSpringUpdate(spring: Spring?) {\n                        if (!toggled && !blockAnim) {\n                            element.springY.currentValue = spring!!.currentValue\n                        }\n                    }\n                })\n            }\n        }\n    }\n\n    fun add(): ChatHead {\n        chatHeads.forEach {\n            it.visibility = View.VISIBLE\n        }\n        val chatHead = ChatHead(this)\n        chatHeads.add(chatHead)\n        var lx = -CHAT_HEAD_OUT_OF_SCREEN_X.toDouble()\n        var ly = 0.0\n        if (topChatHead != null) {\n            lx = topChatHead!!.springX.currentValue\n            ly = topChatHead!!.springY.currentValue\n        }\n\n        setTop(chatHead)\n        destroySpringChains()\n        resetSpringChains()\n\n        blockAnim = true\n\n        chatHeads.forEachIndexed { index, element ->\n            element.springX.currentValue = lx + (chatHeads.size - 1 - index) * CHAT_HEAD_PADDING * if (isOnRight) 1 else -1\n            element.springY.currentValue = ly\n        }\n\n        motionTrackerParams.x = chatHead.springX.currentValue.toInt()\n        motionTrackerParams.y = chatHead.springY.currentValue.toInt()\n        motionTrackerParams.flags = motionTrackerParams.flags and WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE.inv()\n\n        FloatyContentJobService.instance?.windowManager?.updateViewLayout(motionTracker, motionTrackerParams)\n\n        return chatHead\n    }\n\n    fun collapse() {\n        toggled = false\n        collapsing = true\n\n        fixPositions()\n\n        chatHeads.forEach {\n            it.isActive = false\n        }\n        content.hideContent()\n        motionTrackerParams.flags = motionTrackerParams.flags and WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE.inv()\n        FloatyContentJobService.instance?.windowManager?.updateViewLayout(motionTracker, motionTrackerParams)\n\n        params.flags = ((params.flags or WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) and WindowManager.LayoutParams.FLAG_DIM_BEHIND.inv()) and WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL.inv() or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE\n        FloatyContentJobService.instance?.windowManager?.updateViewLayout(this, params)\n    }\n\n    fun changeContent() {\n        val chatHead = chatHeads.find { it.isActive }!!\n\n        //content.messagesView.removeAllViews()\n\n//        for (message in chatHead.messages) {\n//            content.addMessage(message)\n//        }\n    }\n\n    fun getRunningServiceInfo(serviceClass: Class<*>, context: Context): ActivityManager.RunningServiceInfo? {\n        val manager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager\n        for (service in manager.getRunningServices(Integer.MAX_VALUE)) {\n            if (serviceClass.name == service.service.className) {\n                return service\n            }\n        }\n        return null\n    }\n\n    fun hideChatHeads(isClosed:Boolean = false) {\n        if(isClosed){\n            close.hide()\n            postDelayed({\n                topChatHead?.let {\n                    it.springY.currentValue = 0.0\n                    it.springX.currentValue = 0.0\n                }\n                FloatyContentJobService.instance!!.closeWindow(true)\n            }, 300)\n        }else{\n            close.hide()\n            postDelayed({\n                topChatHead?.let {\n                    it.springY.currentValue = 0.0\n                    it.springX.currentValue = 0.0\n                }\n            }, 300)\n        }\n    }\n\n    fun onSpringUpdate(chatHead: ChatHead, spring: Spring, totalVelocity: Int) {\n        val metrics = WindowManagerHelper.getScreenSize()\n        if (topChatHead != null && chatHead == topChatHead!!) {\n            if (horizontalSpringChain != null && spring == chatHead.springX) {\n                horizontalSpringChain!!.controlSpring.currentValue = spring.currentValue\n            }\n            if (verticalSpringChain != null && spring == chatHead.springY) {\n                verticalSpringChain!!.controlSpring.currentValue = spring.currentValue\n            }\n        }\n        var tmpChatHead: ChatHead? = null\n        if (collapsing) tmpChatHead = topChatHead!!\n        else if (chatHead.isActive) tmpChatHead = chatHead\n        if (tmpChatHead != null) {\n            content.x = tmpChatHead.springX.currentValue.toFloat() - metrics.widthPixels.toFloat() + ((chatHeads.size - 1 - chatHeads.indexOf(tmpChatHead)) * (tmpChatHead.width + CHAT_HEAD_EXPANDED_PADDING)) + tmpChatHead.width\n            content.y = tmpChatHead.springY.currentValue.toFloat() - CHAT_HEAD_EXPANDED_MARGIN_TOP\n            content.pivotX = metrics.widthPixels.toFloat() - chatHead.width / 2 - ((chatHeads.size - 1 - chatHeads.indexOf(tmpChatHead)) * (tmpChatHead.width + CHAT_HEAD_EXPANDED_PADDING))\n        }\n        content.pivotY = chatHead.height.toFloat()\n        if (!moving && distance(close.x, topChatHead!!.springX.currentValue.toFloat(), close.y, topChatHead!!.springY.currentValue.toFloat()) < CLOSE_CAPTURE_DISTANCE * CLOSE_CAPTURE_DISTANCE && !captured && close.visibility == View.VISIBLE) {\n            topChatHead!!.springX.springConfig = SpringConfigs.CAPTURING\n            topChatHead!!.springY.springConfig = SpringConfigs.CAPTURING\n            topChatHead!!.springX.endValue = close.springX.endValue\n            topChatHead!!.springY.endValue = close.springY.endValue\n            postDelayed({\n                hideChatHeads(false)\n            }, 300)\n            captured = true\n        }\n        if (wasMoving) {\n            motionTrackerParams.x = if (isOnRight) metrics.widthPixels - chatHead.width else 0\n            lastY = chatHead.springY.currentValue\n            if (abs(chatHead.springY.velocity) > 3000 && (chatHead.springX.currentValue > metrics.widthPixels - chatHead.width + CHAT_HEAD_OUT_OF_SCREEN_X / 2 || chatHead.springX.currentValue < -CHAT_HEAD_OUT_OF_SCREEN_X / 2) && abs(initialVelocityX) > 3000) {\n                chatHead.springY.velocity = 3000.0 * if (initialVelocityY < 0) -1 else 1\n            }\n            if ((chatHead.springX.currentValue < -CHAT_HEAD_OUT_OF_SCREEN_X / 2 && initialVelocityX < -3000 || chatHead.springX.currentValue > metrics.widthPixels - chatHead.width  + CHAT_HEAD_OUT_OF_SCREEN_X / 2) && abs(initialVelocityY) < abs(initialVelocityX)) {\n                chatHead.springY.velocity = 0.0\n            }\n            if (abs(chatHead.springY.velocity) > 500) {\n                if (chatHead.springY.currentValue < 0) {\n                    chatHead.springY.velocity = -500.0\n                } else if (chatHead.springY.currentValue > metrics.heightPixels) {\n                    chatHead.springY.velocity = 500.0\n                }\n            }\n\n            if (!moving) {\n                if (spring === chatHead.springX) {\n                    val xPosition = chatHead.springX.currentValue\n                    if (xPosition + chatHead.width > metrics.widthPixels && chatHead.springX.velocity > 0) {\n                        val newPos = metrics.widthPixels - chatHead.width + CHAT_HEAD_OUT_OF_SCREEN_X\n                        chatHead.springX.springConfig = SpringConfigs.NOT_DRAGGING\n                        chatHead.springX.endValue = newPos.toDouble()\n                        isOnRight = true\n                    } else if (xPosition < 0 && chatHead.springX.velocity < 0) {\n                        chatHead.springX.springConfig = SpringConfigs.NOT_DRAGGING\n                        chatHead.springX.endValue = -CHAT_HEAD_OUT_OF_SCREEN_X.toDouble()\n                        isOnRight = false\n                    }\n                } else if (spring === chatHead.springY) {\n                    val yPosition = chatHead.springY.currentValue\n                    if (yPosition + chatHead.height > metrics.heightPixels && chatHead.springY.velocity > 0) {\n                        chatHead.springY.springConfig = SpringConfigs.NOT_DRAGGING\n                        chatHead.springY.endValue = metrics.heightPixels - chatHead.height.toDouble() -\n                                WindowManagerHelper.dpToPx(25f)\n                    } else if (yPosition < 0 && chatHead.springY.velocity < 0) {\n                        chatHead.springY.springConfig = SpringConfigs.NOT_DRAGGING\n                        chatHead.springY.endValue = 0.0\n                    }\n                }\n            }\n\n            if (abs(totalVelocity) % 10 == 0 && !moving) {\n                motionTrackerParams.y = topChatHead!!.springY.currentValue.toInt()\n                FloatyContentJobService.instance?.windowManager?.updateViewLayout(motionTracker, motionTrackerParams)\n            }\n        }\n    }\n\n    override fun onTouch(v: View?, event: MotionEvent?): Boolean {\n        val metrics = WindowManagerHelper.getScreenSize()\n        if (topChatHead == null) return true\n        when (event!!.action) {\n            MotionEvent.ACTION_DOWN -> {\n                topChatHead?.let {\n                    initialX = it.springX.currentValue.toFloat()\n                    initialY = it.springY.currentValue.toFloat()\n                    initialTouchX = event.rawX\n                    initialTouchY = event.rawY\n                    wasMoving = false\n                    collapsing = false\n                    blockAnim = false\n                    close.show()\n                    it.scaleX = 0.9f\n                    it.scaleY = 0.9f\n                    it.springX.springConfig = SpringConfigs.DRAGGING\n                    it.springY.springConfig = SpringConfigs.DRAGGING\n                    it.springX.setAtRest()\n                    it.springY.setAtRest()\n                }\n                motionTrackerUpdated = false\n                when (velocityTracker) {\n                    null -> velocityTracker = VelocityTracker.obtain()\n                    else -> velocityTracker?.clear()\n                }\n                velocityTracker?.addMovement(event)\n            }\n            MotionEvent.ACTION_UP -> {\n                if (moving) wasMoving = true\n                postDelayed({\n                    close.hide()\n                    if (captured) {\n                        content.removeAllViews()\n                        hideChatHeads(true)\n                    }\n                }, 200)\n                if (captured) return true\n                if (!moving) {\n                    if (!toggled) {\n                        toggled = true\n                        chatHeads.forEachIndexed { index, it ->\n                            it.springX.springConfig = SpringConfigs.NOT_DRAGGING\n                            it.springY.springConfig = SpringConfigs.NOT_DRAGGING\n                            it.springY.endValue = CHAT_HEAD_EXPANDED_MARGIN_TOP.toDouble()\n                            it.springX.endValue = metrics.widthPixels - topChatHead!!.width.toDouble() - (chatHeads.size - 1 - index) * (it.width + CHAT_HEAD_EXPANDED_PADDING).toDouble()\n                        }\n                        motionTrackerParams.flags = motionTrackerParams.flags or WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE\n                        FloatyContentJobService.instance?.windowManager?.updateViewLayout(motionTracker, motionTrackerParams)\n                        params.flags = (params.flags and WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE.inv()) or WindowManager.LayoutParams.FLAG_DIM_BEHIND or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL and WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE.inv()\n                        FloatyContentJobService.instance?.windowManager?.updateViewLayout(this, params)\n                        topChatHead!!.isActive = true\n                        changeContent()\n                        android.os.Handler().postDelayed(\n                            {\n                                content.showContent()\n                            }, 200\n                        )\n                    }\n                } else if (!toggled) {\n                    moving = false\n                    var xVelocity = velocityTracker!!.xVelocity.toDouble()\n                    val yVelocity = velocityTracker!!.yVelocity.toDouble()\n                    var maxVelocityX = 0.0\n                    velocityTracker?.recycle()\n                    velocityTracker = null\n                    if (xVelocity < -3500) {\n                        val newVelocity = ((-topChatHead!!.springX.currentValue -  CHAT_HEAD_OUT_OF_SCREEN_X) * SpringConfigs.DRAGGING.friction)\n                        maxVelocityX = newVelocity - 5000\n                        if (xVelocity > maxVelocityX)\n                            xVelocity = newVelocity - 500\n                    } else if (xVelocity > 3500) {\n                        val newVelocity = ((metrics.widthPixels - topChatHead!!.springX.currentValue - topChatHead!!.width + CHAT_HEAD_OUT_OF_SCREEN_X) * SpringConfigs.DRAGGING.friction)\n                        maxVelocityX = newVelocity + 5000\n                        if (maxVelocityX > xVelocity)\n                            xVelocity = newVelocity + 500\n                    } else if (yVelocity > 20 || yVelocity < -20) {\n                        topChatHead!!.springX.springConfig = SpringConfigs.NOT_DRAGGING\n                        if (topChatHead!!.x >= metrics.widthPixels / 2) {\n                            topChatHead!!.springX.endValue = metrics.widthPixels - topChatHead!!.width + CHAT_HEAD_OUT_OF_SCREEN_X.toDouble()\n                            isOnRight = true\n                        } else {\n                            topChatHead!!.springX.endValue = -CHAT_HEAD_OUT_OF_SCREEN_X.toDouble()\n                            isOnRight = false\n                        }\n                    } else {\n                        topChatHead!!.springX.springConfig = SpringConfigs.NOT_DRAGGING\n                        topChatHead!!.springY.springConfig = SpringConfigs.NOT_DRAGGING\n                        if (topChatHead!!.x >= metrics.widthPixels / 2) {\n                            topChatHead!!.springX.endValue = metrics.widthPixels - topChatHead!!.width +\n                                    CHAT_HEAD_OUT_OF_SCREEN_X.toDouble()\n                            topChatHead!!.springY.endValue = topChatHead!!.y.toDouble()\n                            isOnRight = true\n                        } else {\n                            topChatHead!!.springX.endValue = -CHAT_HEAD_OUT_OF_SCREEN_X.toDouble()\n                            topChatHead!!.springY.endValue = topChatHead!!.y.toDouble()\n                            isOnRight = false\n                        }\n                    }\n                    if (xVelocity < 0) {\n                        topChatHead!!.springX.velocity = max(xVelocity, maxVelocityX)\n                    } else {\n                        topChatHead!!.springX.velocity = min(xVelocity, maxVelocityX)\n                    }\n                    initialVelocityX = topChatHead!!.springX.velocity\n                    initialVelocityY = topChatHead!!.springY.velocity\n                    topChatHead!!.springY.velocity = yVelocity\n                }\n                topChatHead!!.scaleX = 1f\n                topChatHead!!.scaleY = 1f\n            }\n            MotionEvent.ACTION_MOVE -> {\n                if (distance(initialTouchX, event.rawX, initialTouchY, event.rawY) > CHAT_HEAD_DRAG_TOLERANCE.pow(2)) {\n                    moving = true\n                }\n                velocityTracker?.addMovement(event)\n                if (moving) {\n                    close.springX.endValue = (metrics.widthPixels / 2) + (((event.rawX + topChatHead!!.width / 2) / 7) - metrics.widthPixels / 2 / 7) - close.width.toDouble() / 2\n                    close.springY.endValue = (metrics.heightPixels - CLOSE_SIZE) + max(((event.rawY + close.height / 2) / 10) - metrics.heightPixels / 10, -WindowManagerHelper.dpToPx(30f).toFloat()) - WindowManagerHelper.dpToPx(60f).toDouble()\n                    if (distance(close.x + close.width / 2, event.rawX, close.y + close.height / 2, event.rawY) < CLOSE_CAPTURE_DISTANCE * CLOSE_CAPTURE_DISTANCE) {\n                        topChatHead!!.springX.springConfig = SpringConfigs.CAPTURING\n                        topChatHead!!.springY.springConfig = SpringConfigs.CAPTURING\n                        close.springScale.endValue = CLOSE_ADDITIONAL_SIZE.toDouble()\n                        captured = true\n                    } else if (captured) {\n                        topChatHead!!.springX.springConfig = SpringConfigs.CAPTURING\n                        topChatHead!!.springY.springConfig = SpringConfigs.CAPTURING\n                        close.springScale.endValue = 0.0\n                        topChatHead!!.springX.endValue = initialX + (event.rawX - initialTouchX).toDouble()\n                        topChatHead!!.springY.endValue = initialY + (event.rawY - initialTouchY).toDouble()\n                        captured = false\n                        movingOutOfClose = true\n                        postDelayed({ movingOutOfClose = false }, 100)\n                    } else if (!movingOutOfClose) {\n                        topChatHead!!.springX.springConfig = SpringConfigs.DRAGGING\n                        topChatHead!!.springY.springConfig = SpringConfigs.DRAGGING\n                        topChatHead!!.springX.currentValue = initialX + (event.rawX - initialTouchX).toDouble()\n                        topChatHead!!.springY.currentValue = initialY + (event.rawY - initialTouchY).toDouble()\n                        velocityTracker?.computeCurrentVelocity(2000)\n                    }\n                }\n            }\n        }\n        return true\n    }\n}"
  },
  {
    "path": "android/src/main/kotlin/ni/devotion/floaty_head/floating_chathead/Close.kt",
    "content": "package ni.devotion.floaty_head.floating_chathead\n\nimport android.graphics.*\nimport android.os.Build\nimport android.view.*\nimport android.widget.FrameLayout\nimport android.widget.RelativeLayout\nimport androidx.core.content.ContextCompat\nimport com.facebook.rebound.*\nimport ni.devotion.floaty_head.R\nimport ni.devotion.floaty_head.services.FloatyIconService\nimport ni.devotion.floaty_head.utils.Managment\n\nclass Close(var chatHeads: ChatHeads): View(chatHeads.context) {\n    private var params = WindowManager.LayoutParams(\n        ChatHeads.CLOSE_SIZE + ChatHeads.CLOSE_ADDITIONAL_SIZE,\n        ChatHeads.CLOSE_SIZE + ChatHeads.CLOSE_ADDITIONAL_SIZE,\n            WindowManagerHelper.getLayoutFlag(),\n        WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS or WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,\n        PixelFormat.TRANSLUCENT\n    )\n\n    private var gradientParams = FrameLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, WindowManagerHelper.dpToPx(150f))\n    var springSystem = SpringSystem.create()\n    var springY = springSystem.createSpring()\n    var springX = springSystem.createSpring()\n    var springAlpha = springSystem.createSpring()\n    var springScale = springSystem.createSpring()\n    val paint = Paint()\n    val gradient = FrameLayout(context)\n    private var bitmapBg: Bitmap? = null\n    private var bitmapClose: Bitmap? = null\n\n    fun hide() {\n        val metrics = WindowManagerHelper.getScreenSize()\n        springY.endValue = metrics.heightPixels.toDouble() + height\n        springX.endValue = metrics.widthPixels.toDouble() / 2 - width / 2\n        springAlpha.endValue = 0.0\n    }\n\n    fun show() {\n        visibility = View.VISIBLE\n        springAlpha.endValue = 1.0\n    }\n\n    private fun onPositionUpdate() {\n        if (chatHeads.captured) {\n            chatHeads.topChatHead!!.springX.endValue = springX.currentValue + width / 2 - chatHeads.topChatHead!!.width / 2 + 2\n            chatHeads.topChatHead!!.springY.endValue = springY.currentValue + height / 2 - chatHeads.topChatHead!!.height / 2 + 2\n        }\n    }\n\n    init {\n        bitmapBg = Managment.backgroundCloseIcon ?: Bitmap.createScaledBitmap(BitmapFactory.decodeResource(Managment.globalContext!!.resources, R.drawable.close_bg), ChatHeads.CLOSE_SIZE, ChatHeads.CLOSE_SIZE, false)\n        Managment.backgroundCloseIcon?.let {\n            bitmapBg = Bitmap.createScaledBitmap(it, ChatHeads.CLOSE_SIZE, ChatHeads.CLOSE_SIZE, false)\n        }\n        bitmapClose = Managment.closeIcon ?: Bitmap.createScaledBitmap(BitmapFactory.decodeResource(Managment.globalContext!!.resources, R.drawable.close), WindowManagerHelper.dpToPx(28f), WindowManagerHelper.dpToPx(28f), false)\n        Managment.closeIcon?.let {\n            bitmapClose = Bitmap.createScaledBitmap(it, WindowManagerHelper.dpToPx(28f), WindowManagerHelper.dpToPx(28f), false)\n        }\n        this.setLayerType(View.LAYER_TYPE_HARDWARE, paint)\n        visibility = View.INVISIBLE\n        hide()\n        springY.addListener(object : SimpleSpringListener() {\n            override fun onSpringUpdate(spring: Spring) {\n                y = spring.currentValue.toFloat()\n                if (chatHeads.captured && chatHeads.wasMoving) {\n                    chatHeads.topChatHead!!.springY.currentValue = spring.currentValue\n                }\n                onPositionUpdate()\n            }\n        })\n        springX.addListener(object : SimpleSpringListener() {\n            override fun onSpringUpdate(spring: Spring) {\n                x = spring.currentValue.toFloat()\n                onPositionUpdate()\n            }\n        })\n        springScale.addListener(object : SimpleSpringListener() {\n            override fun onSpringUpdate(spring: Spring) {\n                bitmapBg = Managment.backgroundCloseIcon ?: Bitmap.createScaledBitmap(BitmapFactory.decodeResource(Managment.globalContext!!.resources, R.drawable.close_bg), (spring.currentValue + ChatHeads.CLOSE_SIZE).toInt(), (spring.currentValue + ChatHeads.CLOSE_SIZE).toInt(), false)\n                Managment.backgroundCloseIcon?.let {\n                    bitmapBg = Bitmap.createScaledBitmap(it, (spring.currentValue + ChatHeads.CLOSE_SIZE).toInt(), (spring.currentValue + ChatHeads.CLOSE_SIZE).toInt(), false)\n                }\n                invalidate()\n            }\n        })\n        springAlpha.addListener(object : SimpleSpringListener() {\n            override fun onSpringUpdate(spring: Spring) {\n                gradient.alpha = spring.currentValue.toFloat()\n            }\n        })\n        springScale.springConfig = SpringConfigs.CLOSE_SCALE\n        springY.springConfig = SpringConfigs.CLOSE_Y\n        params.gravity = Gravity.START or Gravity.TOP\n        gradientParams.gravity = Gravity.BOTTOM\n        gradient.background = ContextCompat.getDrawable(context, R.drawable.gradient_bg)\n        springAlpha.currentValue = 0.0\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) z = 100f\n        chatHeads.addView(this, params)\n        chatHeads.addView(gradient, gradientParams)\n    }\n\n    override fun onDraw(canvas: Canvas?) {\n        bitmapBg?.let {\n            canvas?.drawBitmap(it, width / 2 - it.width.toFloat() / 2, height / 2 - it.height.toFloat() / 2, paint)\n        }\n        bitmapClose?.let {\n            canvas?.drawBitmap(it, width / 2 - it.width.toFloat() / 2, height / 2 - it.height.toFloat() / 2, paint)\n        }\n    }\n}"
  },
  {
    "path": "android/src/main/kotlin/ni/devotion/floaty_head/floating_chathead/SpringConfig.kt",
    "content": "package ni.devotion.floaty_head.floating_chathead\n\nimport com.facebook.rebound.SpringConfig\n\nobject SpringConfigs {\n    val NOT_DRAGGING = SpringConfig.fromOrigamiTensionAndFriction(60.0, 7.5)\n    val CAPTURING = SpringConfig.fromBouncinessAndSpeed(8.0, 40.0)\n    val CLOSE_SCALE = SpringConfig.fromBouncinessAndSpeed(7.0, 25.0)\n    val CLOSE_Y = SpringConfig.fromBouncinessAndSpeed(3.0, 3.0)\n    val DRAGGING = SpringConfig.fromOrigamiTensionAndFriction(0.0, 5.0)\n    val CONTENT_SCALE = SpringConfig.fromBouncinessAndSpeed(5.0, 40.0)\n}"
  },
  {
    "path": "android/src/main/kotlin/ni/devotion/floaty_head/floating_chathead/WindowManagerHelper.kt",
    "content": "package ni.devotion.floaty_head.floating_chathead\n\nimport android.content.res.Resources\nimport android.os.Build\nimport android.view.WindowManager\nimport android.util.TypedValue\n\nclass WindowManagerHelper {\n    companion object {\n        fun getLayoutFlag(): Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {\n            WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY\n        } else {\n            WindowManager.LayoutParams.TYPE_PHONE\n        }\n\n        fun getScreenSize() = Resources.getSystem().displayMetrics\n        fun dpToPx(dp: Float) = (dp * Resources.getSystem().displayMetrics.density).toInt()\n        fun spToPx(sp: Float) = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, Resources.getSystem().displayMetrics)\n    }\n}"
  },
  {
    "path": "android/src/main/kotlin/ni/devotion/floaty_head/models/Decoration.kt",
    "content": "package ni.devotion.floaty_head.models\n\nimport android.content.Context\nimport ni.devotion.floaty_head.utils.Commons\nimport ni.devotion.floaty_head.utils.NumberUtils\n\nclass Decoration(startColor: Any?, endColor: Any?, borderWidth: Any?, borderRadius: Any?, borderColor: Any?, context: Context?) {\n    val startColor: Int\n    var endColor = 0\n    val borderWidth: Int\n    val borderRadius: Float\n    val borderColor: Int\n    var isGradient = false\n\n    init {\n        this.startColor = NumberUtils.getInt(startColor)\n        if (endColor != null) {\n            this.endColor = NumberUtils.getInt(endColor)\n            isGradient = true\n        } else {\n            isGradient = false\n        }\n        this.borderWidth = Commons.getPixelsFromDp(context!!, NumberUtils.getInt(borderWidth))\n        this.borderRadius = Commons.getPixelsFromDp(context, NumberUtils.getFloat(borderRadius))\n        this.borderColor = NumberUtils.getInt(borderColor)\n    }\n}"
  },
  {
    "path": "android/src/main/kotlin/ni/devotion/floaty_head/models/Margin.kt",
    "content": "package ni.devotion.floaty_head.models\n\nimport ni.devotion.floaty_head.utils.NumberUtils\nimport android.content.Context\nimport ni.devotion.floaty_head.utils.Commons\n\nclass Margin(left: Any?, top: Any?, right: Any?, bottom: Any?, context: Context?) {\n    val left: Int\n    val top: Int\n    val right: Int\n    val bottom: Int\n\n    init {\n        this.left = Commons.getPixelsFromDp(context!!, NumberUtils.getInt(left))\n        this.top = Commons.getPixelsFromDp(context, NumberUtils.getInt(top))\n        this.right = Commons.getPixelsFromDp(context, NumberUtils.getInt(right))\n        this.bottom = Commons.getPixelsFromDp(context, NumberUtils.getInt(bottom))\n    }\n}"
  },
  {
    "path": "android/src/main/kotlin/ni/devotion/floaty_head/models/Padding.kt",
    "content": "package ni.devotion.floaty_head.models\n\nimport ni.devotion.floaty_head.utils.NumberUtils\nimport android.content.Context\nimport ni.devotion.floaty_head.utils.Commons\n\nclass Padding(left: Any?, top: Any?, right: Any?, bottom: Any?, context: Context?) {\n    val left: Int\n    val top: Int\n    val right: Int\n    val bottom: Int\n\n    init {\n        this.left = Commons.getPixelsFromDp(context!!, NumberUtils.getInt(left))\n        this.top = Commons.getPixelsFromDp(context, NumberUtils.getInt(top))\n        this.right = Commons.getPixelsFromDp(context, NumberUtils.getInt(right))\n        this.bottom = Commons.getPixelsFromDp(context, NumberUtils.getInt(bottom))\n    }\n}"
  },
  {
    "path": "android/src/main/kotlin/ni/devotion/floaty_head/services/FloatyContentJobService.kt",
    "content": "package ni.devotion.floaty_head.services\n\nimport android.app.*\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Build\nimport android.os.IBinder\nimport android.util.Log\nimport android.view.WindowManager\nimport androidx.core.app.NotificationCompat\nimport android.graphics.PixelFormat\nimport android.view.WindowManager.LayoutParams\nimport ni.devotion.floaty_head.FloatyHeadPlugin\nimport ni.devotion.floaty_head.R\nimport ni.devotion.floaty_head.floating_chathead.ChatHeads\nimport ni.devotion.floaty_head.utils.Constants.INTENT_EXTRA_PARAMS_MAP\nimport ni.devotion.floaty_head.utils.Managment\nimport java.lang.Exception\nimport java.util.*\n\n\nclass FloatyContentJobService : Service() {\n    companion object {\n        var instance: FloatyContentJobService?= null\n        val CHANNEL_ID = \"ForegroundServiceChannel\"\n        val NOTIFICATION_ID = 1\n        val INTENT_EXTRA_IS_UPDATE_WINDOW = \"IsUpdateWindow\"\n        val INTENT_EXTRA_IS_CLOSE_WINDOW = \"IsCloseWindow\"\n    }\n    var windowManager: WindowManager? = null\n    var context: Context? = null\n    var notification: Notification? = null\n    var chatHeads: ChatHeads? = null\n\n    override fun onCreate() {\n        instance = this\n        createNotificationChannel()\n        showNotificationManager()\n    }\n\n    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {\n        if(null != intent && intent.extras != null) {\n            val paramsMap = (intent.getSerializableExtra(INTENT_EXTRA_PARAMS_MAP) as HashMap<String, Any>?)\n            assert(paramsMap != null)\n            context = this\n            val isCloseWindow = intent.getBooleanExtra(INTENT_EXTRA_IS_CLOSE_WINDOW, false)\n\n            //createWindow()\n            if(!isCloseWindow){\n                val isUpdateWindow = intent.getBooleanExtra(INTENT_EXTRA_IS_CLOSE_WINDOW, false)\n                if(isUpdateWindow){\n                    //updateWindow()\n                }else{\n                    createWindow()\n                }\n            }else{\n                closeWindow(true)\n            }\n        }\n        return START_STICKY\n    }\n\n    fun closeWindow(isEverythingDone: Boolean){\n        try {\n            windowManager?.let { wm ->\n                chatHeads?.let { ch ->\n                    ch.removeAllViews()\n                    wm.removeView(ch)\n                    chatHeads = null\n                }\n            }\n            windowManager = null\n            if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q){\n                Managment.activity?.stopService(Intent(Managment.activity?.applicationContext, this@FloatyContentJobService::class.java))\n            }else{\n                Managment.activity?.startForegroundService(Intent(Managment.activity?.applicationContext, this@FloatyContentJobService::class.java))\n            }\n        }catch(ex: Exception){\n            Log.e(\"TAG\", \"View not found\")\n        }\n        if(isEverythingDone) stopSelf()\n    }\n\n    fun createNotificationChannel() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {\n            val serviceChannel = NotificationChannel(\n                    CHANNEL_ID,\n                    \"Foreground Service Channel\",\n                    NotificationManager.IMPORTANCE_DEFAULT\n            )\n            val manager = getSystemService(NotificationManager::class.java)\n            assert(manager != null)\n            manager.createNotificationChannel(serviceChannel)\n        }\n    }\n\n    fun createWindow() {\n        setWindowManager()\n        val params:WindowManager.LayoutParams\n        params = LayoutParams()\n        params.width = LayoutParams.MATCH_PARENT\n        params.height = LayoutParams.WRAP_CONTENT\n        params.format = PixelFormat.TRANSLUCENT\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)\n        {\n        params.type = LayoutParams.TYPE_APPLICATION_OVERLAY\n        params.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL or LayoutParams.FLAG_SHOW_WHEN_LOCKED or LayoutParams.FLAG_NOT_FOCUSABLE\n        }\n        else\n        {\n        params.type = LayoutParams.TYPE_SYSTEM_ALERT or LayoutParams.TYPE_SYSTEM_OVERLAY\n        params.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL or LayoutParams.FLAG_NOT_FOCUSABLE\n        }\n        chatHeads = ChatHeads(this)\n        chatHeads?.add()\n    }\n\n    fun showNotificationManager() {\n        val notificationIntent = Intent(this, FloatyHeadPlugin::class.java)\n        val pendingIntent = PendingIntent.getActivity(this,\n                0, notificationIntent, 0)\n        notification = if(Managment.notificationIcon == null) {\n            NotificationCompat.Builder(this, \"ForegroundServiceChannel\")\n                    .setContentTitle(\"${Managment.notificationTitle} is Currently Running\")\n                    .setSmallIcon(R.drawable.ic_chathead)\n                    .setContentIntent(pendingIntent)\n                    .build()\n        }else{\n            NotificationCompat.Builder(this, \"ForegroundServiceChannel\")\n                    .setContentTitle(\"${Managment.notificationTitle} is Currently Running\")\n                    .setLargeIcon(Managment.notificationIcon)\n                    .setContentIntent(pendingIntent)\n                    .build()\n        }\n        startForeground(NOTIFICATION_ID, notification)\n    }\n\n    override fun onBind(p0: Intent?): IBinder? {\n        return null\n    }\n\n    override fun onDestroy() {\n        val notificationManager = applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager\n        assert(notificationManager != null)\n        notificationManager.cancel(NOTIFICATION_ID)\n        super.onDestroy()\n    }\n\n    private fun setWindowManager() = windowManager ?: run { windowManager = getSystemService(WINDOW_SERVICE) as WindowManager }\n}"
  },
  {
    "path": "android/src/main/kotlin/ni/devotion/floaty_head/services/FloatyIconService.kt",
    "content": "package ni.devotion.floaty_head.services\n\nimport android.annotation.SuppressLint\nimport android.app.*\nimport android.content.Intent\nimport android.os.Build\nimport android.os.IBinder\nimport android.util.Log\nimport androidx.core.app.NotificationCompat\nimport ni.devotion.floaty_head.FloatyHeadPlugin\nimport ni.devotion.floaty_head.FloatyHeadPlugin.Companion.context\nimport ni.devotion.floaty_head.MainActivity\nimport ni.devotion.floaty_head.R\nimport ni.devotion.floaty_head.utils.Managment\n\nclass FloatyIconService: Service() {\n    companion object {\n        lateinit var instance: FloatyIconService\n        var notificationManager: NotificationManager? = null\n        var notification: Notification? = null\n    }\n    val channel_id = \"2208\"\n    val floaty_notification_id = 2208\n\n    override fun onCreate() {\n        instance = this\n        super.onCreate()\n    }\n\n    @SuppressLint(\"NewApi\")\n    private fun initNotificationManager() {\n        notificationManager ?: run {\n            context?.let {\n                notificationManager = it.getSystemService(NotificationManager::class.java)\n            } ?: run {\n                Log.e(\"TAG\", \"Context is null. Can't show the FloatyNotification\")\n                return\n            }\n        }\n    }\n\n    fun createNotificationChannel() {\n        initNotificationManager()\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {\n            val serviceChannel = NotificationChannel(\n                    channel_id,\n                    \"Foreground Service Channel\",\n                    NotificationManager.IMPORTANCE_DEFAULT\n            )\n            notificationManager?.createNotificationChannel(serviceChannel)\n        }\n    }\n\n    fun showNotificationManager() {\n        val notificationIntent = Intent(this, MainActivity::class.java)\n        val pendingIntent = PendingIntent.getActivity(this,\n                0, notificationIntent, 0)\n        notification = if(Managment.notificationIcon == null) {\n            NotificationCompat.Builder(this, \"ForegroundServiceChannel\")\n                    .setContentTitle(\"${Managment.notificationTitle} is Currently Running\")\n                    .setSmallIcon(R.drawable.ic_chathead)\n                    .setContentIntent(pendingIntent)\n                    .build()\n        }else{\n            NotificationCompat.Builder(this, \"ForegroundServiceChannel\")\n                    .setContentTitle(\"${Managment.notificationTitle} is Currently Running\")\n                    .setLargeIcon(Managment.notificationIcon)\n                    .setContentIntent(pendingIntent)\n                    .build()\n        }\n        startForeground(floaty_notification_id, notification)\n    }\n\n    override fun onDestroy() {\n        super.onDestroy()\n    }\n\n    override fun onBind(intent: Intent): IBinder? {\n        return null\n    }\n\n    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {\n        createNotificationChannel()\n        showNotificationManager()\n        return START_NOT_STICKY\n    }\n}"
  },
  {
    "path": "android/src/main/kotlin/ni/devotion/floaty_head/utils/Commons.kt",
    "content": "package ni.devotion.floaty_head.utils\n\nimport android.content.Context\nimport android.graphics.Typeface\nimport android.util.TypedValue\nimport android.view.Gravity\nimport android.widget.LinearLayout\nimport androidx.annotation.Nullable\nimport ni.devotion.floaty_head.models.Margin\nimport ni.devotion.floaty_head.utils.Constants.KEY_MARGIN\n\n\nobject Commons {\n    fun getMapFromObject(map: Map<String, Any>, key: String?): Map<String, Any>? {\n        return map[key] as Map<String, Any>?\n    }\n\n    fun getMapListFromObject(map: Map<String, Any>, key: String?): List<Map<String, Any>>? {\n        return map[key] as List<Map<String, Any>>?\n    }\n\n    fun getSpFromPixels(context: Context, px: Float): Float {\n        val scaledDensity = context.resources.displayMetrics.scaledDensity\n        return px / scaledDensity\n    }\n\n    fun getPixelsFromDp(context: Context, dp: Int): Int {\n        return if (dp == -1) -1 else TypedValue.applyDimension(\n                TypedValue.COMPLEX_UNIT_DIP, dp.toFloat(), context.resources.displayMetrics).toInt()\n    }\n\n    fun getPixelsFromDp(context: Context, dp: Float): Float {\n        return if (dp == -1f) (-1).toFloat() else TypedValue.applyDimension(\n                TypedValue.COMPLEX_UNIT_DIP, dp, context.resources.displayMetrics)\n    }\n\n    fun getGravity(@Nullable gravityStr: String?, defVal: Int): Int {\n        var gravity = defVal\n        if (gravityStr != null) {\n            when (gravityStr) {\n                \"top\" -> gravity = Gravity.TOP\n                \"center\" -> gravity = Gravity.CENTER\n                \"bottom\" -> gravity = Gravity.BOTTOM\n                \"leading\" -> gravity = Gravity.START\n                \"trailing\" -> gravity = Gravity.END\n            }\n        }\n        return gravity\n    }\n\n    fun getFontWeight(@Nullable fontWeightStr: String?, defVal: Int): Int {\n        var fontWeight = defVal\n        if (fontWeightStr != null) {\n            fontWeight = when (fontWeightStr) {\n                \"normal\" -> Typeface.NORMAL\n                \"bold\" -> Typeface.BOLD\n                \"italic\" -> Typeface.ITALIC\n                \"bold_italic\" -> Typeface.BOLD_ITALIC\n                else -> Typeface.NORMAL\n            }\n        }\n        return fontWeight\n    }\n\n    fun setMargin(context: Context?, params: LinearLayout.LayoutParams, map: Map<String, Any?>) {\n        val margin: Margin = UiBuilder.getMargin(context, map[KEY_MARGIN])\n        params.setMargins(margin.left, margin.top, margin.right, margin.bottom)\n    }\n}\n"
  },
  {
    "path": "android/src/main/kotlin/ni/devotion/floaty_head/utils/Constants.kt",
    "content": "package ni.devotion.floaty_head.utils\n\nobject Constants {\n\n    val CHANNEL = \"ni.devotion.floaty_head\"\n    val METHOD_CHANNEL = \"ni.devotion/floaty_head\"\n    val BACKGROUND_CHANNEL = \"ni.devotion.floaty_head/background\"\n\n    val SHARED_PREF_FLOATY_HEAD = \"ni.devotion.floaty_head\"\n    val CALLBACK_HANDLE_KEY = \"callback_handler\"\n    val CODE_CALLBACK_HANDLE_KEY = \"code_callback_handler\"\n\n    val INTENT_EXTRA_PARAMS_MAP = \"intent_params_map\"\n\n    val CALLBACK_TYPE_ONCLICK = \"onClick\"\n\n    //Internal plugin param map keys\n    val KEY_HEADER = \"header\"\n    val KEY_BODY = \"body\"\n    val KEY_FOOTER = \"footer\"\n    val KEY_IS_SHOW_FOOTER = \"isShowFooter\"\n    val KEY_TITLE = \"title\"\n    val KEY_SUBTITLE = \"subTitle\"\n    val KEY_TAG = \"tag\"\n    val KEY_TEXT = \"text\"\n    val KEY_FONT_SIZE = \"fontSize\"\n    val KEY_FONT_WEIGHT = \"fontWeight\"\n    val KEY_TEXT_COLOR = \"textColor\"\n    val KEY_BUTTON = \"button\"\n    val KEY_BUTTONS_LIST = \"buttons\"\n    val KEY_BUTTON_POSITION = \"buttonPosition\"\n    val KEY_BUTTONS_LIST_POSITION = \"buttonsPosition\"\n    val KEY_DECORATION = \"decoration\"\n    val KEY_START_COLOR = \"startColor\"\n    val KEY_END_COLOR = \"endColor\"\n    val KEY_BORDER_WIDTH = \"borderWidth\"\n    val KEY_BORDER_COLOR = \"borderColor\"\n    val KEY_BORDER_RADIUS = \"borderRadius\"\n    val KEY_GRAVITY = \"gravity\"\n    val KEY_PADDING = \"padding\"\n    val KEY_MARGIN = \"margin\"\n    val KEY_LEFT = \"left\"\n    val KEY_TOP = \"top\"\n    val KEY_RIGHT = \"right\"\n    val KEY_BOTTOM = \"bottom\"\n    val KEY_WIDTH = \"width\"\n    val KEY_HEIGHT = \"height\"\n    val KEY_ROWS = \"rows\"\n    val KEY_COLUMNS = \"columns\"\n}"
  },
  {
    "path": "android/src/main/kotlin/ni/devotion/floaty_head/utils/ImageHelper.kt",
    "content": "package ni.devotion.floaty_head.utils\n\nimport android.annotation.SuppressLint\nimport android.content.Context\nimport android.graphics.*\nimport android.graphics.drawable.BitmapDrawable\nimport android.graphics.drawable.Drawable\nimport android.os.Build\nimport androidx.core.content.ContextCompat\nimport ni.devotion.floaty_head.floating_chathead.ChatHeads\n\nclass ImageHelper {\n    companion object {\n        fun getCircularBitmap(bitmap: Bitmap): Bitmap {\n            val output = Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)\n            val canvas = Canvas(output)\n            val paint = Paint()\n            val rect = Rect(0, 0, bitmap.width, bitmap.height)\n            paint.isAntiAlias = true\n            canvas.drawARGB(0, 0, 0, 0)\n            paint.color = -0xbdbdbe\n            canvas.drawCircle(output.width.toFloat() / 2, output.height.toFloat() / 2, output.width.toFloat() / 2, paint)\n            paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)\n            canvas.drawBitmap(bitmap, rect, rect, paint)\n            return Bitmap.createScaledBitmap(output, ChatHeads.CHAT_HEAD_SIZE, ChatHeads.CHAT_HEAD_SIZE, true)\n        }\n\n        fun addShadow(src: Bitmap): Bitmap {\n            val bmOut = Bitmap.createBitmap(src.width + 10, src.height + 20, Bitmap.Config.ARGB_8888)\n            val centerX = (bmOut.width / 2 - src.width / 2).toFloat()\n            val centerY = (bmOut.height / 2 - src.height / 2).toFloat()\n            val canvas = Canvas(bmOut)\n            canvas.drawColor(0, PorterDuff.Mode.CLEAR)\n            val ptBlur = Paint()\n            ptBlur.maskFilter = BlurMaskFilter(6f, BlurMaskFilter.Blur.NORMAL)\n            val offsetXY = IntArray(2)\n            val bmAlpha = src.extractAlpha(ptBlur, offsetXY)\n            val ptAlphaColor = Paint()\n            ptAlphaColor.color = Color.argb(80, 0, 0, 0)\n            canvas.drawBitmap(bmAlpha, centerX + offsetXY[0], centerY  + offsetXY[1] + 4f, ptAlphaColor)\n            bmAlpha.recycle()\n            canvas.drawBitmap(src, centerX, centerY,null)\n            return bmOut\n        }\n    }\n\n    @SuppressLint(\"UseCompatLoadingForDrawables\")\n    fun drawableFromVector(context: Context, drawableId: Int): Drawable {\n        val drawable = when {\n            Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> context.getDrawable(drawableId)\n            else -> ContextCompat.getDrawable(context, drawableId)\n        }\n        val bitmap = Bitmap.createBitmap(drawable!!.intrinsicWidth, drawable.intrinsicHeight, Bitmap.Config.ARGB_8888)\n        val canvas = Canvas(bitmap)\n        drawable.setBounds(0, 0, canvas.width, canvas.height)\n        drawable.draw(canvas)\n        return BitmapDrawable(context.resources, Bitmap.createScaledBitmap(bitmap, drawable.intrinsicWidth, drawable.intrinsicHeight, false))\n    }\n}\n"
  },
  {
    "path": "android/src/main/kotlin/ni/devotion/floaty_head/utils/Managment.kt",
    "content": "package ni.devotion.floaty_head.utils\n\nimport android.app.ActionBar\nimport android.app.Activity\nimport android.content.Context\nimport android.graphics.Bitmap\nimport android.view.View\nimport android.widget.FrameLayout\nimport java.util.HashMap\nimport io.flutter.plugin.common.PluginRegistry\nimport io.flutter.plugin.common.PluginRegistry.Registrar\nimport ni.devotion.floaty_head.services.FloatyIconService\nimport java.util.concurrent.atomic.AtomicBoolean\n\n/**\n * Handle all the states of the project, and all the custom icons including the body that is gonna be displayed inside the chathead.\n */\nobject Managment {\n    var floatingIcon: Bitmap? = null\n    var closeIcon: Bitmap? = null\n    var backgroundCloseIcon: Bitmap? = null\n    var notificationTitle: String = \"Floaty_head\"\n    var notificationIcon: Bitmap? = null\n    var paramsMap: HashMap<String, Any>? = null\n    var headersMap: Map<String, Any>? = null\n    var bodyMap: Map<String, Any>? = null\n    var footerMap: Map<String, Any>? = null\n    var headerView: View? = null\n    var bodyView: View? = null\n    var footerView: View? = null\n    var layoutParams: FrameLayout.LayoutParams? = null\n    var pluginRegistrantC: PluginRegistry.PluginRegistrantCallback? = null\n    var floatyIconService: FloatyIconService? = null\n    var globalContext: Context? = null\n    var activity: Activity? = null\n    var sIsIsolateRunning = AtomicBoolean(false)\n}"
  },
  {
    "path": "android/src/main/kotlin/ni/devotion/floaty_head/utils/NumberUtils.kt",
    "content": "package ni.devotion.floaty_head.utils\n\nimport android.util.Log\n\n/**\n * Class used for convert any number to [float] or [int] and retrieve any number from an [any] object.\n */\nobject NumberUtils {\n    private const val TAG = \"NumberUtils\"\n    fun getFloat(`object`: Any?) = getNumber(`object`).toFloat()\n    fun getInt(`object`: Any?) = getNumber(`object`).toInt()\n    private fun getNumber(`object`: Any?): Number {\n        var `val`: Number = 0\n        if (`object` != null) {\n            try {\n                `val` = `object` as Number\n            } catch (ex: Exception) {\n                Log.d(TAG, ex.toString())\n            }\n        }\n        return `val`\n    }\n}"
  },
  {
    "path": "android/src/main/kotlin/ni/devotion/floaty_head/utils/UiBuilder.kt",
    "content": "package ni.devotion.floaty_head.utils\n\nimport android.content.Context\nimport android.graphics.Typeface\nimport android.graphics.drawable.GradientDrawable\nimport android.os.Build\nimport android.util.TypedValue\nimport android.view.View\nimport android.widget.Button\nimport android.widget.LinearLayout\nimport android.widget.TextView\nimport ni.devotion.floaty_head.FloatyHeadPlugin\nimport ni.devotion.floaty_head.models.Decoration\nimport ni.devotion.floaty_head.models.Margin\nimport ni.devotion.floaty_head.models.Padding\nimport ni.devotion.floaty_head.utils.Constants.CALLBACK_TYPE_ONCLICK\nimport ni.devotion.floaty_head.utils.Constants.KEY_BORDER_COLOR\nimport ni.devotion.floaty_head.utils.Constants.KEY_BORDER_RADIUS\nimport ni.devotion.floaty_head.utils.Constants.KEY_BORDER_WIDTH\nimport ni.devotion.floaty_head.utils.Constants.KEY_BOTTOM\nimport ni.devotion.floaty_head.utils.Constants.KEY_DECORATION\nimport ni.devotion.floaty_head.utils.Constants.KEY_END_COLOR\nimport ni.devotion.floaty_head.utils.Constants.KEY_FONT_SIZE\nimport ni.devotion.floaty_head.utils.Constants.KEY_FONT_WEIGHT\nimport ni.devotion.floaty_head.utils.Constants.KEY_HEIGHT\nimport ni.devotion.floaty_head.utils.Constants.KEY_LEFT\nimport ni.devotion.floaty_head.utils.Constants.KEY_MARGIN\nimport ni.devotion.floaty_head.utils.Constants.KEY_PADDING\nimport ni.devotion.floaty_head.utils.Constants.KEY_RIGHT\nimport ni.devotion.floaty_head.utils.Constants.KEY_START_COLOR\nimport ni.devotion.floaty_head.utils.Constants.KEY_TAG\nimport ni.devotion.floaty_head.utils.Constants.KEY_TEXT\nimport ni.devotion.floaty_head.utils.Constants.KEY_TEXT_COLOR\nimport ni.devotion.floaty_head.utils.Constants.KEY_TOP\nimport ni.devotion.floaty_head.utils.Constants.KEY_WIDTH\n\n\n/**\n * This class is responsible to create all the content that is displayed inside the chathead.\n * if you wanna add your own widget, please be sure to create your [function], also remember to\n * create your class with the styles and components needed for that widget to be displayed.\n */\nobject UiBuilder {\n    fun getTextView(context: Context?, textMap: Map<String, Any>?): TextView? {\n        if (textMap == null) return null\n        val textView = TextView(context)\n        textView.text = textMap[KEY_TEXT] as String?\n        textView.setTypeface(textView.typeface, Commons.getFontWeight(textMap[KEY_FONT_WEIGHT] as String?, Typeface.NORMAL))\n        textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, NumberUtils.getFloat(textMap[KEY_FONT_SIZE]))\n        textView.setTextColor(NumberUtils.getInt(textMap[KEY_TEXT_COLOR]))\n        val padding: Padding = getPadding(context, textMap[KEY_PADDING])\n        textView.setPadding(padding.left, padding.top, padding.right, padding.bottom)\n        return textView\n    }\n\n    fun getPadding(context: Context?, `object`: Any?): Padding {\n        val paddingMap = `object` as Map<String, Any>?\n                ?: return Padding(0, 0, 0, 0, context)\n        return Padding(paddingMap[KEY_LEFT], paddingMap[KEY_TOP], paddingMap[KEY_RIGHT], paddingMap[KEY_BOTTOM], context)\n    }\n\n    fun getMargin(context: Context?, `object`: Any?): Margin {\n        val marginMap = `object` as Map<String, Any>?\n                ?: return Margin(0, 0, 0, 0, context)\n        return Margin(marginMap[KEY_LEFT], marginMap[KEY_TOP], marginMap[KEY_RIGHT], marginMap[KEY_BOTTOM], context)\n    }\n\n    fun getDecoration(context: Context?, `object`: Any?): Decoration? {\n        val decorationMap = `object` as Map<String, Any>? ?: return null\n        return Decoration(decorationMap[KEY_START_COLOR], decorationMap[KEY_END_COLOR],\n                decorationMap[KEY_BORDER_WIDTH], decorationMap[KEY_BORDER_RADIUS],\n                decorationMap[KEY_BORDER_COLOR], context)\n    }\n\n    fun getButtonView(context: Context?, buttonMap: Map<String, Any>?): Button? {\n        buttonMap ?: return null\n        val button = Button(context)\n        val buttonText = getTextView(context, Commons.getMapFromObject(buttonMap, KEY_TEXT))!!\n        button.text = buttonText.text\n        val tag = buttonMap[KEY_TAG]\n        button.tag = tag\n        button.textSize = Commons.getSpFromPixels(context!!, buttonText.textSize)\n        button.setTextColor(buttonText.textColors)\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) button.elevation = 10f\n        val params = LinearLayout.LayoutParams(\n                Commons.getPixelsFromDp(context, buttonMap[KEY_WIDTH] as Int),\n                Commons.getPixelsFromDp(context, buttonMap[KEY_HEIGHT] as Int),\n                1.0f)\n        val buttonMargin: Margin = getMargin(context, buttonMap[KEY_MARGIN])\n        params.setMargins(buttonMargin.left, buttonMargin.top, buttonMargin.right, buttonMargin.bottom.coerceAtMost(4))\n        button.layoutParams = params\n        val padding: Padding = getPadding(context, buttonMap[KEY_PADDING])\n        button.setPadding(padding.left, padding.top, padding.right, padding.bottom)\n        val decoration: Decoration? = getDecoration(context, buttonMap[KEY_DECORATION])\n        decoration?.let{\n            val gd = getGradientDrawable(it)\n            button.background = gd\n        }\n        button.setOnClickListener {\n            if(!Managment.sIsIsolateRunning.get()){\n                FloatyHeadPlugin.instance.startCallBackHandler(context)\n            }\n            FloatyHeadPlugin.instance.invokeCallBack(context, CALLBACK_TYPE_ONCLICK, tag!!)\n        }\n        return button\n    }\n\n    fun getGradientDrawable(decoration: Decoration?): GradientDrawable {\n        val gd = GradientDrawable()\n        if (decoration!!.isGradient) {\n            val colors = intArrayOf(decoration.startColor, decoration.endColor)\n            gd.colors = colors\n            gd.orientation = GradientDrawable.Orientation.LEFT_RIGHT\n        } else {\n            gd.setColor(decoration.startColor)\n        }\n        gd.cornerRadius = decoration.borderRadius\n        gd.setStroke(decoration.borderWidth, decoration.borderColor)\n        return gd\n    }\n}"
  },
  {
    "path": "android/src/main/kotlin/ni/devotion/floaty_head/views/BodyView.kt",
    "content": "package ni.devotion.floaty_head.views\n\nimport android.content.Context\nimport android.graphics.Color\nimport android.view.Gravity\nimport android.view.View\nimport android.widget.LinearLayout\nimport ni.devotion.floaty_head.utils.Commons.getGravity\nimport ni.devotion.floaty_head.utils.Commons.getMapFromObject\nimport ni.devotion.floaty_head.utils.Commons.setMargin\nimport ni.devotion.floaty_head.utils.Constants.KEY_COLUMNS\nimport ni.devotion.floaty_head.utils.Constants.KEY_DECORATION\nimport ni.devotion.floaty_head.utils.Constants.KEY_GRAVITY\nimport ni.devotion.floaty_head.utils.Constants.KEY_PADDING\nimport ni.devotion.floaty_head.utils.Constants.KEY_ROWS\nimport ni.devotion.floaty_head.utils.Constants.KEY_TEXT\nimport ni.devotion.floaty_head.utils.UiBuilder.getDecoration\nimport ni.devotion.floaty_head.utils.UiBuilder.getGradientDrawable\nimport ni.devotion.floaty_head.utils.UiBuilder.getPadding\nimport ni.devotion.floaty_head.utils.UiBuilder.getTextView\n\n\nclass BodyView(private val context: Context, private val bodyMap: Map<String, Any>) {\n    val view: LinearLayout\n        get() {\n            val linearLayout = LinearLayout(context)\n            linearLayout.orientation = LinearLayout.VERTICAL\n            val decoration = getDecoration(context, bodyMap[KEY_DECORATION])\n            if (decoration != null) {\n                val gd = getGradientDrawable(decoration)\n                linearLayout.background = gd\n            } else {\n                linearLayout.setBackgroundColor(Color.WHITE)\n            }\n            val params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,\n                    LinearLayout.LayoutParams.WRAP_CONTENT)\n            setMargin(context, params, bodyMap)\n            linearLayout.layoutParams = params\n            val padding = getPadding(context, bodyMap[KEY_PADDING])\n            linearLayout.setPadding(padding.left, padding.top, padding.right, padding.bottom)\n            val rowsMap = bodyMap[KEY_ROWS] as List<Map<String, Any>>?\n            if (rowsMap != null) {\n                for (i in rowsMap.indices) {\n                    val row = rowsMap[i]\n                    linearLayout.addView(createRow(row))\n                }\n            }\n            return linearLayout\n        }\n\n    private fun createRow(rowMap: Map<String, Any>): View {\n        val linearLayout = LinearLayout(context)\n        linearLayout.orientation = LinearLayout.HORIZONTAL\n        val params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,\n                LinearLayout.LayoutParams.WRAP_CONTENT)\n        setMargin(context, params, rowMap)\n        linearLayout.layoutParams = params\n        linearLayout.gravity = getGravity(rowMap[KEY_GRAVITY] as String?, Gravity.START)\n        val padding = getPadding(context, rowMap[KEY_PADDING])\n        linearLayout.setPadding(padding.left, padding.top, padding.right, padding.bottom)\n        val decoration = getDecoration(context, rowMap[KEY_DECORATION])\n        if (decoration != null) {\n            val gd = getGradientDrawable(decoration)\n            linearLayout.background = gd\n        }\n        val columnsMap = rowMap[KEY_COLUMNS] as List<Map<String, Any>>?\n        if (columnsMap != null) {\n            for (j in columnsMap.indices) {\n                val column = columnsMap[j]\n                linearLayout.addView(createColumn(column))\n            }\n        }\n        return linearLayout\n    }\n\n    private fun createColumn(columnMap: Map<String, Any>): View {\n        val columnLayout = LinearLayout(context)\n        columnLayout.orientation = LinearLayout.HORIZONTAL\n        val params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,\n                LinearLayout.LayoutParams.WRAP_CONTENT)\n        setMargin(context, params, columnMap)\n        columnLayout.layoutParams = params\n        val padding = getPadding(context, columnMap[KEY_PADDING])\n        columnLayout.setPadding(padding.left, padding.top, padding.right, padding.bottom)\n        val decoration = getDecoration(context, columnMap[KEY_DECORATION])\n        if (decoration != null) {\n            val gd = getGradientDrawable(decoration)\n            columnLayout.background = gd\n        }\n        val textView = getTextView(context, getMapFromObject(columnMap, KEY_TEXT))\n        columnLayout.addView(textView)\n        return columnLayout\n    }\n}\n"
  },
  {
    "path": "android/src/main/kotlin/ni/devotion/floaty_head/views/FooterView.kt",
    "content": "package ni.devotion.floaty_head.views\n\nimport android.content.Context\nimport android.view.Gravity\nimport android.view.ViewGroup\nimport android.widget.Button\nimport android.widget.LinearLayout\nimport ni.devotion.floaty_head.utils.Commons.getGravity\nimport ni.devotion.floaty_head.utils.Commons.getMapFromObject\nimport ni.devotion.floaty_head.utils.Commons.getMapListFromObject\nimport ni.devotion.floaty_head.utils.Constants.KEY_BUTTONS_LIST\nimport ni.devotion.floaty_head.utils.Constants.KEY_BUTTONS_LIST_POSITION\nimport ni.devotion.floaty_head.utils.Constants.KEY_DECORATION\nimport ni.devotion.floaty_head.utils.Constants.KEY_IS_SHOW_FOOTER\nimport ni.devotion.floaty_head.utils.Constants.KEY_PADDING\nimport ni.devotion.floaty_head.utils.Constants.KEY_TEXT\nimport ni.devotion.floaty_head.utils.UiBuilder.getButtonView\nimport ni.devotion.floaty_head.utils.UiBuilder.getDecoration\nimport ni.devotion.floaty_head.utils.UiBuilder.getGradientDrawable\nimport ni.devotion.floaty_head.utils.UiBuilder.getPadding\nimport ni.devotion.floaty_head.utils.UiBuilder.getTextView\n\n\nclass FooterView(private val context: Context, private val footerMap: Map<String, Any>) {\n    val view: LinearLayout\n        get() {\n            val linearLayout = LinearLayout(context)\n            linearLayout.orientation = LinearLayout.HORIZONTAL\n            val params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,\n                    LinearLayout.LayoutParams.WRAP_CONTENT)\n            val footerPadding = getPadding(context, footerMap[KEY_PADDING])\n            linearLayout.setPadding(footerPadding.left, footerPadding.top, footerPadding.right, footerPadding.bottom)\n            linearLayout.layoutParams = params\n            val decoration = getDecoration(context, footerMap[KEY_DECORATION])\n            if (decoration != null) {\n                val gd = getGradientDrawable(decoration)\n                linearLayout.background = gd\n            }\n            if (footerMap[KEY_IS_SHOW_FOOTER] as Boolean) {\n                val textMap = getMapFromObject(footerMap, KEY_TEXT)\n                val buttonsMap: List<Map<String, Any>>? = getMapListFromObject(footerMap, KEY_BUTTONS_LIST)\n                val textView = getTextView(context, textMap)\n                val buttonsView: MutableList<Button?> = ArrayList()\n                for (buttonMap in buttonsMap!!) {\n                    buttonsView.add(getButtonView(context, buttonMap))\n                }\n                val buttonsPosition = footerMap[KEY_BUTTONS_LIST_POSITION] as String?\n                if (textView != null) {\n                    if (buttonsView.size > 0) {\n                        if (\"leading\" == buttonsPosition) {\n                            for (buttonView in buttonsView) {\n                                linearLayout.addView(buttonView)\n                            }\n                            linearLayout.addView(textView)\n                        } else {\n                            val param = LinearLayout.LayoutParams(\n                                    ViewGroup.LayoutParams.WRAP_CONTENT,\n                                    ViewGroup.LayoutParams.WRAP_CONTENT,\n                                    1.0f\n                            )\n                            textView.layoutParams = param\n                            linearLayout.addView(textView)\n                            for (buttonView in buttonsView) {\n                                linearLayout.addView(buttonView)\n                            }\n                        }\n                    } else {\n                        linearLayout.addView(textView)\n                    }\n                } else {\n                    for (buttonView in buttonsView) {\n                        linearLayout.addView(buttonView)\n                    }\n                    linearLayout.gravity = getGravity(buttonsPosition, Gravity.FILL)\n                }\n            }\n            return linearLayout\n        }\n\n}\n"
  },
  {
    "path": "android/src/main/kotlin/ni/devotion/floaty_head/views/HeaderView.kt",
    "content": "package ni.devotion.floaty_head.views\n\nimport android.content.Context\nimport android.graphics.Color\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.LinearLayout\nimport android.widget.RelativeLayout\nimport ni.devotion.floaty_head.utils.Commons.getMapFromObject\nimport ni.devotion.floaty_head.utils.Constants.KEY_BUTTON\nimport ni.devotion.floaty_head.utils.Constants.KEY_BUTTON_POSITION\nimport ni.devotion.floaty_head.utils.Constants.KEY_DECORATION\nimport ni.devotion.floaty_head.utils.Constants.KEY_PADDING\nimport ni.devotion.floaty_head.utils.Constants.KEY_SUBTITLE\nimport ni.devotion.floaty_head.utils.Constants.KEY_TITLE\nimport ni.devotion.floaty_head.utils.UiBuilder.getButtonView\nimport ni.devotion.floaty_head.utils.UiBuilder.getDecoration\nimport ni.devotion.floaty_head.utils.UiBuilder.getGradientDrawable\nimport ni.devotion.floaty_head.utils.UiBuilder.getPadding\nimport ni.devotion.floaty_head.utils.UiBuilder.getTextView\n\n\nclass HeaderView(private val context: Context, private val headerMap: Map<String, Any>) {\n    val relativeView: RelativeLayout\n        get() {\n            val relativeLayout = RelativeLayout(context)\n            relativeLayout.layoutParams = RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT)\n            val decoration = getDecoration(context, headerMap[KEY_DECORATION])\n            if (decoration != null) {\n                val gd = getGradientDrawable(decoration)\n                relativeLayout.background = gd\n            } else {\n                relativeLayout.setBackgroundColor(Color.WHITE)\n            }\n            val titleMap = getMapFromObject(headerMap, KEY_TITLE)\n            val subTitleMap = getMapFromObject(headerMap, KEY_SUBTITLE)\n            val buttonMap = getMapFromObject(headerMap, KEY_BUTTON)\n            val padding = getPadding(context, headerMap[KEY_PADDING])\n            relativeLayout.setPadding(padding.left, padding.top, padding.right, padding.bottom)\n            val isShowButton = buttonMap != null\n            assert(titleMap != null)\n            val textColumn = createTextColumn(titleMap, subTitleMap)\n            if (isShowButton) {\n                val buttonPosition = headerMap[KEY_BUTTON_POSITION] as String?\n                val button = getButtonView(context, buttonMap)\n                if (\"leading\" == buttonPosition) {\n                    relativeLayout.addView(button)\n                    relativeLayout.addView(textColumn)\n                } else {\n                    relativeLayout.addView(textColumn)\n                    relativeLayout.addView(button)\n                }\n            } else {\n                relativeLayout.addView(textColumn)\n            }\n            return relativeLayout\n        }\n\n    //assert titleMap != null;\n    val view: LinearLayout\n        get() {\n            val linearLayout = LinearLayout(context)\n            linearLayout.orientation = LinearLayout.HORIZONTAL\n            val decoration = getDecoration(context, headerMap[KEY_DECORATION])\n            if (decoration != null) {\n                val gd = getGradientDrawable(decoration)\n                linearLayout.background = gd\n            } else {\n                linearLayout.setBackgroundColor(Color.WHITE)\n            }\n            linearLayout.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)\n            val titleMap = getMapFromObject(headerMap, KEY_TITLE)\n            val subTitleMap = getMapFromObject(headerMap, KEY_SUBTITLE)\n            val buttonMap = getMapFromObject(headerMap, KEY_BUTTON)\n            val padding = getPadding(context, headerMap[KEY_PADDING])\n            linearLayout.setPadding(padding.left, padding.top, padding.right, padding.bottom)\n            val isShowButton = buttonMap != null\n            assert(titleMap != null)\n            val textColumn = createTextColumn(titleMap, subTitleMap)\n            if (isShowButton) {\n                val buttonPosition = headerMap[KEY_BUTTON_POSITION] as String?\n                val button = getButtonView(context, buttonMap)\n                if (\"leading\" == buttonPosition) {\n                    linearLayout.addView(button)\n                    textColumn?.let{\n                        linearLayout.addView(it)\n                    }\n                } else {\n                    textColumn?.let{\n                        val param = LinearLayout.LayoutParams(\n                                ViewGroup.LayoutParams.WRAP_CONTENT,\n                                ViewGroup.LayoutParams.WRAP_CONTENT,\n                                1.0f\n                        )\n                        it.layoutParams = param\n                        linearLayout.addView(it)\n                    }\n                    linearLayout.addView(button)\n                }\n            } else {\n                linearLayout.addView(textColumn)\n            }\n            return linearLayout\n        }\n\n\n    fun createTextColumn(titleMap: Map<String, Any>?, subTitleMap: Map<String, Any>?): View? {\n        val titleView = getTextView(context, titleMap)\n        if (subTitleMap != null) {\n            val linearLayout = LinearLayout(context)\n            linearLayout.orientation = LinearLayout.VERTICAL\n            linearLayout.addView(titleView)\n            linearLayout.addView(getTextView(context, subTitleMap))\n            return linearLayout\n        }\n        return titleView\n    }\n}\n"
  },
  {
    "path": "android/src/main/kotlin/ni/devotion/floaty_head/views/RowView.kt",
    "content": "package ni.devotion.floaty_head.views\n\nimport android.content.Context\nimport android.widget.LinearLayout\nimport ni.devotion.floaty_head.utils.Commons.getMapFromObject\nimport ni.devotion.floaty_head.utils.UiBuilder.getPadding\nimport ni.devotion.floaty_head.utils.UiBuilder.getTextView\n\nclass RowView(private val context: Context, private val rowMap: Map<String, Any>) {\n    val view: LinearLayout\n        get() {\n            val linearLayout = LinearLayout(context)\n            linearLayout.orientation = LinearLayout.HORIZONTAL\n            linearLayout.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)\n            val columnsMap = rowMap[\"columns\"] as List<Map<String, Any>>?\n            val padding = getPadding(context, getMapFromObject(rowMap, \"padding\"))\n            linearLayout.setPadding(padding.left, padding.top, padding.right, padding.bottom)\n            if (columnsMap != null) {\n                for (i in columnsMap.indices) {\n                    val eachColumn = columnsMap[i]\n                    val textView = getTextView(context, getMapFromObject(eachColumn, \"text\"))\n                    linearLayout.addView(textView)\n                }\n            }\n            return linearLayout\n        }\n\n}"
  },
  {
    "path": "android/src/main/res/drawable/gradient_bg.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <gradient\n            android:startColor=\"#59000000\"\n            android:endColor=\"#00ffffff\"\n            android:angle=\"90\"\n    />\n</shape>"
  },
  {
    "path": "android/src/main/res/drawable/ic_chathead.xml",
    "content": "<vector android:height=\"64dp\" android:viewportHeight=\"512\"\n    android:viewportWidth=\"512\" android:width=\"64dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"#64B5F6\" android:pathData=\"M448,170.85v0.5c0,99 -80,179.4 -178.2,179.4h-24.3l-34,45.6c-9.1,12.2 -23.6,19.6 -38.9,19.6c-4.2,0 -8.4,-0.6 -12.6,-1.7c20.3,20.8 48.7,33.7 80,33.7h40l43.2,57.6c3.1,4.1 7.9,6.4 12.8,6.4c1.7,0 3.4,-0.3 5.1,-0.8c6.5,-2.2 10.9,-8.3 10.9,-15.2v-48h48c61.8,0 112,-50.2 112,-112v-64C512,227.45 485.8,188.85 448,170.85z\"/>\n    <path android:fillColor=\"#2196F3\" android:pathData=\"M272,0.05H144c-79.4,0 -144,64.6 -144,144v32c0,79.4 64.6,144 144,144h16v48c0,6.9 4.4,13 10.9,15.2c1.7,0.5 3.4,0.8 5.1,0.8c4.9,0 9.7,-2.3 12.8,-6.4l43.2,-57.6h40c79.4,0 144,-64.6 144,-144v-32C416,64.65 351.4,0.05 272,0.05z\"/>\n</vector>\n"
  },
  {
    "path": "android/src/main/res/layout/fragment_float.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    android:id=\"@+id/contentLayout\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_marginTop=\"80dp\"\n    android:orientation=\"vertical\"\n    android:clickable=\"true\">\n</LinearLayout>"
  },
  {
    "path": "android/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#71b5bd</color>\n    <color name=\"colorPrimaryDark\">#4A777C</color>\n    <color name=\"colorAccent\">#2e4f61</color>\n\n    <color name=\"colorPrimaryDarkMode\">#8e4a42</color>\n    <color name=\"colorPrimarySubDarkMode\">#b58883</color>\n    <color name=\"colorAccentDarkMode\">#d1b09e</color>\n\n    <color name=\"transparent\">#00ffffff</color>\n    <color name=\"md_semitrans_blue\">#47d500f9</color>\n    <color name=\"md_semitran_green\">#6A2ACADF</color>\n    <color name=\"md_semitrans_green\">#6B8BC34A</color>\n    <color name=\"colorDivider\">#1f000000</color>\n\n    <!--reds-->\n    <color name=\"md_red_50\">#FFEBEE</color>\n    <color name=\"md_red_100\">#FFCDD2</color>\n    <color name=\"md_red_200\">#EF9A9A</color>\n    <color name=\"md_red_300\">#E57373</color>\n    <color name=\"md_red_400\">#EF5350</color>\n    <color name=\"md_red_500\">#F44336</color>\n    <color name=\"md_red_600\">#E53935</color>\n    <color name=\"md_red_700\">#D32F2F</color>\n    <color name=\"md_red_800\">#C62828</color>\n    <color name=\"md_red_900\">#B71C1C</color>\n    <color name=\"md_red_A100\">#FF8A80</color>\n    <color name=\"md_red_A200\">#FF5252</color>\n    <color name=\"md_red_A400\">#FF1744</color>\n    <color name=\"md_red_A700\">#D50000</color>\n\n    <!-- pinks -->\n    <color name=\"md_pink_50\">#FCE4EC</color>\n    <color name=\"md_pink_100\">#F8BBD0</color>\n    <color name=\"md_pink_200\">#F48FB1</color>\n    <color name=\"md_pink_300\">#F06292</color>\n    <color name=\"md_pink_400\">#EC407A</color>\n    <color name=\"md_pink_500\">#E91E63</color>\n    <color name=\"md_pink_600\">#D81B60</color>\n    <color name=\"md_pink_700\">#C2185B</color>\n    <color name=\"md_pink_800\">#AD1457</color>\n    <color name=\"md_pink_900\">#880E4F</color>\n    <color name=\"md_pink_A100\">#FF80AB</color>\n    <color name=\"md_pink_A200\">#FF4081</color>\n    <color name=\"md_pink_A400\">#F50057</color>\n    <color name=\"md_pink_A700\">#C51162</color>\n\n    <!-- purples -->\n    <color name=\"md_purple_50\">#F3E5F5</color>\n    <color name=\"md_purple_100\">#E1BEE7</color>\n    <color name=\"md_purple_200\">#CE93D8</color>\n    <color name=\"md_purple_300\">#BA68C8</color>\n    <color name=\"md_purple_400\">#AB47BC</color>\n    <color name=\"md_purple_500\">#9C27B0</color>\n    <color name=\"md_purple_600\">#8E24AA</color>\n    <color name=\"md_purple_700\">#7B1FA2</color>\n    <color name=\"md_purple_800\">#6A1B9A</color>\n    <color name=\"md_purple_900\">#4A148C</color>\n    <color name=\"md_purple_A100\">#EA80FC</color>\n    <color name=\"md_purple_A200\">#E040FB</color>\n    <color name=\"md_purple_A400\">#D500F9</color>\n    <color name=\"md_purple_A700\">#AA00FF</color>\n\n    <!-- deep purples -->\n    <color name=\"md_deep_purple_50\">#EDE7F6</color>\n    <color name=\"md_deep_purple_100\">#D1C4E9</color>\n    <color name=\"md_deep_purple_200\">#B39DDB</color>\n    <color name=\"md_deep_purple_300\">#9575CD</color>\n    <color name=\"md_deep_purple_400\">#7E57C2</color>\n    <color name=\"md_deep_purple_500\">#673AB7</color>\n    <color name=\"md_deep_purple_600\">#5E35B1</color>\n    <color name=\"md_deep_purple_700\">#512DA8</color>\n    <color name=\"md_deep_purple_800\">#4527A0</color>\n    <color name=\"md_deep_purple_900\">#311B92</color>\n    <color name=\"md_deep_purple_A100\">#B388FF</color>\n    <color name=\"md_deep_purple_A200\">#7C4DFF</color>\n    <color name=\"md_deep_purple_A400\">#651FFF</color>\n    <color name=\"md_deep_purple_A700\">#6200EA</color>\n\n    <!-- indigo -->\n    <color name=\"md_indigo_50\">#E8EAF6</color>\n    <color name=\"md_indigo_100\">#C5CAE9</color>\n    <color name=\"md_indigo_200\">#9FA8DA</color>\n    <color name=\"md_indigo_300\">#7986CB</color>\n    <color name=\"md_indigo_400\">#5C6BC0</color>\n    <color name=\"md_indigo_500\">#3F51B5</color>\n    <color name=\"md_indigo_600\">#3949AB</color>\n    <color name=\"md_indigo_700\">#303F9F</color>\n    <color name=\"md_indigo_800\">#283593</color>\n    <color name=\"md_indigo_900\">#1A237E</color>\n    <color name=\"md_indigo_A100\">#8C9EFF</color>\n    <color name=\"md_indigo_A200\">#536DFE</color>\n    <color name=\"md_indigo_A400\">#3D5AFE</color>\n    <color name=\"md_indigo_A700\">#304FFE</color>\n\n    <!--blue-->\n    <color name=\"md_blue_50\">#E3F2FD</color>\n    <color name=\"md_blue_100\">#BBDEFB</color>\n    <color name=\"md_blue_200\">#90CAF9</color>\n    <color name=\"md_blue_300\">#64B5F6</color>\n    <color name=\"md_blue_400\">#42A5F5</color>\n    <color name=\"md_blue_500\">#2196F3</color>\n    <color name=\"md_blue_600\">#1E88E5</color>\n    <color name=\"md_blue_700\">#1976D2</color>\n    <color name=\"md_blue_800\">#1565C0</color>\n    <color name=\"md_blue_900\">#0D47A1</color>\n    <color name=\"md_blue_A100\">#82B1FF</color>\n    <color name=\"md_blue_A200\">#448AFF</color>\n    <color name=\"md_blue_A400\">#2979FF</color>\n    <color name=\"md_blue_A700\">#2962FF</color>\n\n    <!-- light blue-->\n    <color name=\"md_light_blue_50\">#E1F5FE</color>\n    <color name=\"md_light_blue_100\">#B3E5FC</color>\n    <color name=\"md_light_blue_200\">#81D4fA</color>\n    <color name=\"md_light_blue_300\">#4fC3F7</color>\n    <color name=\"md_light_blue_400\">#29B6FC</color>\n    <color name=\"md_light_blue_500\">#03A9F4</color>\n    <color name=\"md_light_blue_600\">#039BE5</color>\n    <color name=\"md_light_blue_700\">#0288D1</color>\n    <color name=\"md_light_blue_800\">#0277BD</color>\n    <color name=\"md_light_blue_900\">#01579B</color>\n    <color name=\"md_light_blue_A100\">#80D8FF</color>\n    <color name=\"md_light_blue_A200\">#40C4FF</color>\n    <color name=\"md_light_blue_A400\">#00B0FF</color>\n    <color name=\"md_light_blue_A700\">#0091EA</color>\n\n    <!-- cyan -->\n    <color name=\"md_cyan_50\">#E0F7FA</color>\n    <color name=\"md_cyan_100\">#B2EBF2</color>\n    <color name=\"md_cyan_200\">#80DEEA</color>\n    <color name=\"md_cyan_300\">#4DD0E1</color>\n    <color name=\"md_cyan_400\">#26C6DA</color>\n    <color name=\"md_cyan_500\">#00BCD4</color>\n    <color name=\"md_cyan_600\">#00ACC1</color>\n    <color name=\"md_cyan_700\">#0097A7</color>\n    <color name=\"md_cyan_800\">#00838F</color>\n    <color name=\"md_cyan_900\">#006064</color>\n    <color name=\"md_cyan_A100\">#84FFFF</color>\n    <color name=\"md_cyan_A200\">#18FFFF</color>\n    <color name=\"md_cyan_A400\">#00E5FF</color>\n    <color name=\"md_cyan_A700\">#00B8D4</color>\n\n    <!-- teal -->\n    <color name=\"md_teal_50\">#E0F2F1</color>\n    <color name=\"md_teal_100\">#B2DFDB</color>\n    <color name=\"md_teal_200\">#80CBC4</color>\n    <color name=\"md_teal_300\">#4DB6AC</color>\n    <color name=\"md_teal_400\">#26A69A</color>\n    <color name=\"md_teal_500\">#009688</color>\n    <color name=\"md_teal_600\">#00897B</color>\n    <color name=\"md_teal_700\">#00796B</color>\n    <color name=\"md_teal_800\">#00695C</color>\n    <color name=\"md_teal_900\">#004D40</color>\n    <color name=\"md_teal_A100\">#A7FFEB</color>\n    <color name=\"md_teal_A200\">#64FFDA</color>\n    <color name=\"md_teal_A400\">#1DE9B6</color>\n    <color name=\"md_teal_A700\">#00BFA5</color>\n\n    <!-- green -->\n    <color name=\"md_green_50\">#E8F5E9</color>\n    <color name=\"md_green_100\">#C8E6C9</color>\n    <color name=\"md_green_200\">#A5D6A7</color>\n    <color name=\"md_green_300\">#81C784</color>\n    <color name=\"md_green_400\">#66BB6A</color>\n    <color name=\"md_green_500\">#4CAF50</color>\n    <color name=\"md_green_600\">#43A047</color>\n    <color name=\"md_green_700\">#388E3C</color>\n    <color name=\"md_green_800\">#2E7D32</color>\n    <color name=\"md_green_900\">#1B5E20</color>\n    <color name=\"md_green_A100\">#B9F6CA</color>\n    <color name=\"md_green_A200\">#69F0AE</color>\n    <color name=\"md_green_A400\">#00E676</color>\n    <color name=\"md_green_A700\">#00C853</color>\n\n    <!--light green-->\n    <color name=\"md_light_green_50\">#F1F8E9</color>\n    <color name=\"md_light_green_100\">#DCEDC8</color>\n    <color name=\"md_light_green_200\">#C5E1A5</color>\n    <color name=\"md_light_green_300\">#AED581</color>\n    <color name=\"md_light_green_400\">#9CCC65</color>\n    <color name=\"md_light_green_500\">#8BC34A</color>\n    <color name=\"md_light_green_600\">#7CB342</color>\n    <color name=\"md_light_green_700\">#689F38</color>\n    <color name=\"md_light_green_800\">#558B2F</color>\n    <color name=\"md_light_green_900\">#33691E</color>\n    <color name=\"md_light_green_A100\">#CCFF90</color>\n    <color name=\"md_light_green_A200\">#B2FF59</color>\n    <color name=\"md_light_green_A400\">#76FF03</color>\n    <color name=\"md_light_green_A700\">#64DD17</color>\n\n    <!-- lime-->\n    <color name=\"md_lime_50\">#F9FBE7</color>\n    <color name=\"md_lime_100\">#F0F4C3</color>\n    <color name=\"md_lime_200\">#E6EE9C</color>\n    <color name=\"md_lime_300\">#DCE775</color>\n    <color name=\"md_lime_400\">#D4E157</color>\n    <color name=\"md_lime_500\">#CDDC39</color>\n    <color name=\"md_lime_600\">#C0CA33</color>\n    <color name=\"md_lime_700\">#A4B42B</color>\n    <color name=\"md_lime_800\">#9E9D24</color>\n    <color name=\"md_lime_900\">#827717</color>\n    <color name=\"md_lime_A100\">#F4FF81</color>\n    <color name=\"md_lime_A200\">#EEFF41</color>\n    <color name=\"md_lime_A400\">#C6FF00</color>\n    <color name=\"md_lime_A700\">#AEEA00</color>\n\n    <!--yellow -->\n    <color name=\"md_yellow_50\">#FFFDE7</color>\n    <color name=\"md_yellow_100\">#FFF9C4</color>\n    <color name=\"md_yellow_200\">#FFF590</color>\n    <color name=\"md_yellow_300\">#FFF176</color>\n    <color name=\"md_yellow_400\">#FFEE58</color>\n    <color name=\"md_yellow_500\">#FFEB3B</color>\n    <color name=\"md_yellow_600\">#FDD835</color>\n    <color name=\"md_yellow_700\">#FBC02D</color>\n    <color name=\"md_yellow_800\">#F9A825</color>\n    <color name=\"md_yellow_900\">#F57F17</color>\n    <color name=\"md_yellow_A100\">#FFFF82</color>\n    <color name=\"md_yellow_A200\">#FFFF00</color>\n    <color name=\"md_yellow_A400\">#FFEA00</color>\n    <color name=\"md_yellow_A700\">#FFD600</color>\n\n    <!--amber-->\n    <color name=\"md_amber_50\">#FFF8E1</color>\n    <color name=\"md_amber_100\">#FFECB3</color>\n    <color name=\"md_amber_200\">#FFE082</color>\n    <color name=\"md_amber_300\">#FFD54F</color>\n    <color name=\"md_amber_400\">#FFCA28</color>\n    <color name=\"md_amber_500\">#FFC107</color>\n    <color name=\"md_amber_600\">#FFB300</color>\n    <color name=\"md_amber_700\">#FFA000</color>\n    <color name=\"md_amber_800\">#FF8F00</color>\n    <color name=\"md_amber_900\">#FF6F00</color>\n    <color name=\"md_amber_A100\">#FFE57F</color>\n    <color name=\"md_amber_A200\">#FFD740</color>\n    <color name=\"md_amber_A400\">#FFC400</color>\n    <color name=\"md_amber_A700\">#FFAB00</color>\n\n    <!--orange-->\n    <color name=\"md_orange_50\">#FFF3E0</color>\n    <color name=\"md_orange_100\">#FFE0B2</color>\n    <color name=\"md_orange_200\">#FFCC80</color>\n    <color name=\"md_orange_300\">#FFB74D</color>\n    <color name=\"md_orange_400\">#FFA726</color>\n    <color name=\"md_orange_500\">#FF9800</color>\n    <color name=\"md_orange_600\">#FB8C00</color>\n    <color name=\"md_orange_700\">#F57C00</color>\n    <color name=\"md_orange_800\">#EF6C00</color>\n    <color name=\"md_orange_900\">#E65100</color>\n    <color name=\"md_orange_A100\">#FFD180</color>\n    <color name=\"md_orange_A200\">#FFAB40</color>\n    <color name=\"md_orange_A400\">#FF9100</color>\n    <color name=\"md_orange_A700\">#FF6D00</color>\n\n    <!--deep orange-->\n    <color name=\"md_deep_orange_50\">#FBE9A7</color>\n    <color name=\"md_deep_orange_100\">#FFCCBC</color>\n    <color name=\"md_deep_orange_200\">#FFAB91</color>\n    <color name=\"md_deep_orange_300\">#FF8A65</color>\n    <color name=\"md_deep_orange_400\">#FF7043</color>\n    <color name=\"md_deep_orange_500\">#FF5722</color>\n    <color name=\"md_deep_orange_600\">#F4511E</color>\n    <color name=\"md_deep_orange_700\">#E64A19</color>\n    <color name=\"md_deep_orange_800\">#D84315</color>\n    <color name=\"md_deep_orange_900\">#BF360C</color>\n    <color name=\"md_deep_orange_A100\">#FF9E80</color>\n    <color name=\"md_deep_orange_A200\">#FF6E40</color>\n    <color name=\"md_deep_orange_A400\">#FF3D00</color>\n    <color name=\"md_deep_orange_A700\">#DD2600</color>\n\n    <!--brown -->\n    <color name=\"md_brown_50\">#EFEBE9</color>\n    <color name=\"md_brown_100\">#D7CCC8</color>\n    <color name=\"md_brown_200\">#BCAAA4</color>\n    <color name=\"md_brown_300\">#A1887F</color>\n    <color name=\"md_brown_400\">#8D6E63</color>\n    <color name=\"md_brown_500\">#795548</color>\n    <color name=\"md_brown_600\">#6D4C41</color>\n    <color name=\"md_brown_700\">#5D4037</color>\n    <color name=\"md_brown_800\">#4E342E</color>\n    <color name=\"md_brown_900\">#3E2723</color>\n\n    <!--grey-->\n    <color name=\"md_grey_50\">#FAFAFA</color>\n    <color name=\"md_grey_100\">#F5F5F5</color>\n    <color name=\"md_grey_200\">#EEEEEE</color>\n    <color name=\"md_grey_300\">#E0E0E0</color>\n    <color name=\"md_grey_400\">#BDBDBD</color>\n    <color name=\"md_grey_500\">#9E9E9E</color>\n    <color name=\"md_grey_600\">#757575</color>\n    <color name=\"md_grey_700\">#616161</color>\n    <color name=\"md_grey_800\">#424242</color>\n    <color name=\"md_grey_900\">#212121</color>\n    <color name=\"md_black_1000\">#000000</color>\n    <color name=\"md_white_1000\">#ffffff</color>\n    <color name=\"md_white_900\">#F8F3F3</color>\n\n    <!--blue grey-->\n    <color name=\"md_blue_grey_50\">#ECEFF1</color>\n    <color name=\"md_blue_grey_100\">#CFD8DC</color>\n    <color name=\"md_blue_grey_200\">#B0BBC5</color>\n    <color name=\"md_blue_grey_300\">#90A4AE</color>\n    <color name=\"md_blue_grey_400\">#78909C</color>\n    <color name=\"md_blue_grey_500\">#607D8B</color>\n    <color name=\"md_blue_grey_600\">#546E7A</color>\n    <color name=\"md_blue_grey_700\">#455A64</color>\n    <color name=\"md_blue_grey_800\">#37474F</color>\n    <color name=\"md_blue_grey_900\">#263238</color>\n\n    <color name=\"material_petal\">#F98866</color>\n    <color name=\"material_poppy\">#FF420E</color>\n    <color name=\"material_stem\">#80BD9E</color>\n    <color name=\"material_spring_green\">#89DA59</color>\n\n    <color name=\"black_overlay\">#66000000</color>\n</resources>\n"
  },
  {
    "path": "android/src/main/res/values/strings.xml",
    "content": "<resources>\n    <!-- TODO: Remove or change this placeholder text -->\n    <string name=\"hello_blank_fragment\">Hello blank fragment</string>\n</resources>"
  },
  {
    "path": "android/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\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    <style name=\"AppTheme.NoActionBar\">\n        <item name=\"windowActionBar\">false</item>\n        <item name=\"windowNoTitle\">true</item>\n    </style>\n\n    <style name=\"AppTheme.AppBarOverlay\" parent=\"ThemeOverlay.AppCompat.Dark.ActionBar\" />\n\n    <style name=\"AppTheme.PopupOverlay\" parent=\"ThemeOverlay.AppCompat.Light\" />\n\n</resources>\n"
  },
  {
    "path": "example/.gitignore",
    "content": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.iws\n.idea/\n\n# The .vscode folder contains launch configuration and tasks you configure in\n# VS Code which you may wish to be included in version control, so this line\n# is commented out by default.\n#.vscode/\n\n# Flutter/Dart/Pub related\n**/doc/api/\n**/ios/Flutter/.last_build_id\n.dart_tool/\n.flutter-plugins\n.flutter-plugins-dependencies\n.packages\n.pub-cache/\n.pub/\n/build/\n\n# Web related\nlib/generated_plugin_registrant.dart\n\n# Symbolication related\napp.*.symbols\n\n# Obfuscation related\napp.*.map.json\n"
  },
  {
    "path": "example/.metadata",
    "content": "# This file tracks properties of this Flutter project.\n# Used by Flutter tool to assess capabilities and perform upgrades etc.\n#\n# This file should be version controlled and should not be manually edited.\n\nversion:\n  revision: 216dee60c0cc9449f0b29bcf922974d612263e24\n  channel: stable\n\nproject_type: app\n"
  },
  {
    "path": "example/README.md",
    "content": "# floaty_head_example\n\nDemonstrates how to use the floaty_head plugin.\n\n## Getting Started\n\nThis project is a starting point for a Flutter application.\n\nA few resources to get you started if this is your first Flutter project:\n\n- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)\n- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)\n\nFor help getting started with Flutter, view our\n[online documentation](https://flutter.dev/docs), which offers tutorials,\nsamples, guidance on mobile development, and a full API reference.\n"
  },
  {
    "path": "example/android/.gitignore",
    "content": "gradle-wrapper.jar\n/.gradle\n/captures/\n/gradlew\n/gradlew.bat\n/local.properties\nGeneratedPluginRegistrant.java\n\n# Remember to never publicly share your keystore.\n# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app\nkey.properties\n"
  },
  {
    "path": "example/android/app/build.gradle",
    "content": "def localProperties = new Properties()\ndef localPropertiesFile = rootProject.file('local.properties')\nif (localPropertiesFile.exists()) {\n    localPropertiesFile.withReader('UTF-8') { reader ->\n        localProperties.load(reader)\n    }\n}\n\ndef flutterRoot = localProperties.getProperty('flutter.sdk')\nif (flutterRoot == null) {\n    throw new GradleException(\"Flutter SDK not found. Define location with flutter.sdk in the local.properties file.\")\n}\n\ndef flutterVersionCode = localProperties.getProperty('flutter.versionCode')\nif (flutterVersionCode == null) {\n    flutterVersionCode = '1'\n}\n\ndef flutterVersionName = localProperties.getProperty('flutter.versionName')\nif (flutterVersionName == null) {\n    flutterVersionName = '1.0'\n}\n\napply plugin: 'com.android.application'\napply plugin: 'kotlin-android'\napply from: \"$flutterRoot/packages/flutter_tools/gradle/flutter.gradle\"\n\nandroid {\n    compileSdkVersion 29\n\n    sourceSets {\n        main.java.srcDirs += 'src/main/kotlin'\n    }\n\n    lintOptions {\n        disable 'InvalidPackage'\n    }\n\n    defaultConfig {\n        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).\n        applicationId \"ni.devotion.floaty_head_example\"\n        minSdkVersion 16\n        targetSdkVersion 29\n        versionCode flutterVersionCode.toInteger()\n        versionName flutterVersionName\n    }\n\n    buildTypes {\n        release {\n            // TODO: Add your own signing config for the release build.\n            // Signing with the debug keys for now, so `flutter run --release` works.\n            signingConfig signingConfigs.debug\n        }\n    }\n}\n\nflutter {\n    source '../..'\n}\n\ndependencies {\n    implementation \"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version\"\n}\n"
  },
  {
    "path": "example/android/app/src/debug/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"ni.devotion.floaty_head_example\">\n    <!-- Flutter needs it to communicate with the running application\n         to allow setting breakpoints, to provide hot reload, etc.\n    -->\n    <uses-permission android:name=\"android.permission.INTERNET\"/>\n</manifest>\n"
  },
  {
    "path": "example/android/app/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"ni.devotion.floaty_head_example\">\n    <!-- io.flutter.app.FlutterApplication is an android.app.Application that\n         calls FlutterMain.startInitialization(this); in its onCreate method.\n         In most cases you can leave this as-is, but you if you want to provide\n         additional functionality it is fine to subclass or reimplement\n         FlutterApplication and put your custom class here. -->\n    <application\n        android:name=\"io.flutter.app.FlutterApplication\"\n        android:label=\"floaty_head_example\"\n        android:hardwareAccelerated=\"false\"\n        android:icon=\"@mipmap/ic_launcher\">\n        <activity\n            android:name=\".MainActivity\"\n            android:launchMode=\"singleTop\"\n            android:theme=\"@style/LaunchTheme\"\n            android:configChanges=\"orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode\"\n            android:hardwareAccelerated=\"true\"\n            android:windowSoftInputMode=\"adjustResize\">\n            <!-- Specifies an Android theme to apply to this Activity as soon as\n                 the Android process has started. This theme is visible to the user\n                 while the Flutter UI initializes. After that, this theme continues\n                 to determine the Window background behind the Flutter UI. -->\n            <meta-data\n              android:name=\"io.flutter.embedding.android.NormalTheme\"\n              android:resource=\"@style/NormalTheme\"\n              />\n            <!-- Displays an Android View that continues showing the launch screen\n                 Drawable until Flutter paints its first frame, then this splash\n                 screen fades out. A splash screen is useful to avoid any visual\n                 gap between the end of Android's launch screen and the painting of\n                 Flutter's first frame. -->\n            <meta-data\n              android:name=\"io.flutter.embedding.android.SplashScreenDrawable\"\n              android:resource=\"@drawable/launch_background\"\n              />\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        <!-- Don't delete the meta-data below.\n             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->\n        <meta-data\n            android:name=\"flutterEmbedding\"\n            android:value=\"2\" />\n    </application>\n</manifest>\n"
  },
  {
    "path": "example/android/app/src/main/kotlin/ni/devotion/floaty_head_example/Application.kt",
    "content": "package ni.devotion.floaty_head_example;\n\nimport androidx.annotation.NonNull\nimport ni.devotion.floaty_head.FloatyHeadPlugin\nimport ni.devotion.floaty_head.utils.Managment\nimport io.flutter.embedding.android.FlutterActivity\nimport io.flutter.plugins.GeneratedPluginRegistrant\nimport io.flutter.app.FlutterApplication\nimport io.flutter.plugin.common.PluginRegistry\nimport io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback\nimport io.flutter.embedding.engine.FlutterEngine\n\n/**\n * For the [Application] class also use the\n * ```kotlin\n * Managment.pluginRegistrantC = this\n * ```\n * to set the callback between Kotlin/Dart.\n */\nclass Application : FlutterApplication(), PluginRegistry.PluginRegistrantCallback {\n      override fun onCreate() {\n          super.onCreate()\n          FloatyHeadPlugin().setPluginRegistrant(this)\n          Managment.pluginRegistrantC = this\n      }\n\n     override fun registerWith(registry: PluginRegistry) {\n        FloatyHeadPlugin().registerWith(registry.registrarFor(this.packageName))\n     }\n     \n  }"
  },
  {
    "path": "example/android/app/src/main/kotlin/ni/devotion/floaty_head_example/MainActivity.kt",
    "content": "package ni.devotion.floaty_head_example;\n\nimport android.os.Bundle;\nimport androidx.annotation.NonNull\nimport io.flutter.embedding.android.FlutterActivity\nimport io.flutter.embedding.engine.FlutterEngine\nimport io.flutter.plugins.GeneratedPluginRegistrant\n\nclass MainActivity: FlutterActivity() {\n\n    /**\n     * When using this plugin please set the [Application().onCreate()]\n     * if this isn't setted the chathead cannot communicate with the dart-client code\n     */\n    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {\n        GeneratedPluginRegistrant.registerWith(flutterEngine);\n        Application().onCreate()\n    }\n}"
  },
  {
    "path": "example/android/app/src/main/res/drawable/launch_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Modify this file to customize your launch splash screen -->\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item android:drawable=\"@android:color/white\" />\n\n    <!-- You can insert your own image assets here -->\n    <!-- <item>\n        <bitmap\n            android:gravity=\"center\"\n            android:src=\"@mipmap/launch_image\" />\n    </item> -->\n</layer-list>\n"
  },
  {
    "path": "example/android/app/src/main/res/values/styles.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <!-- Theme applied to the Android Window while the process is starting -->\n    <style name=\"LaunchTheme\" parent=\"@android:style/Theme.Black.NoTitleBar\">\n        <!-- Show a splash screen on the activity. Automatically removed when\n             Flutter draws its first frame -->\n        <item name=\"android:windowBackground\">@drawable/launch_background</item>\n    </style>\n    <!-- Theme applied to the Android Window as soon as the process has started.\n         This theme determines the color of the Android Window while your\n         Flutter UI initializes, as well as behind your Flutter UI while its\n         running.\n         \n         This Theme is only used starting with V2 of Flutter's Android embedding. -->\n    <style name=\"NormalTheme\" parent=\"@android:style/Theme.Black.NoTitleBar\">\n        <item name=\"android:windowBackground\">@android:color/white</item>\n    </style>\n</resources>\n"
  },
  {
    "path": "example/android/app/src/profile/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"ni.devotion.floaty_head_example\">\n    <!-- Flutter needs it to communicate with the running application\n         to allow setting breakpoints, to provide hot reload, etc.\n    -->\n    <uses-permission android:name=\"android.permission.INTERNET\"/>\n</manifest>\n"
  },
  {
    "path": "example/android/build.gradle",
    "content": "buildscript {\n    ext.kotlin_version = '1.3.50'\n    repositories {\n        google()\n        jcenter()\n    }\n\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.6.1'\n        classpath \"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version\"\n    }\n}\n\nallprojects {\n    repositories {\n        google()\n        jcenter()\n    }\n}\n\nrootProject.buildDir = '../build'\nsubprojects {\n    project.buildDir = \"${rootProject.buildDir}/${project.name}\"\n}\nsubprojects {\n    project.evaluationDependsOn(':app')\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "example/android/gradle/wrapper/gradle-wrapper.properties",
    "content": "#Fri Jun 23 08:50:38 CEST 2017\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-6.3-all.zip\n"
  },
  {
    "path": "example/android/gradle.properties",
    "content": "org.gradle.jvmargs=-Xmx1536M\nandroid.useAndroidX=true\nandroid.enableJetifier=true\nandroid.enableR8=true\n"
  },
  {
    "path": "example/android/settings.gradle",
    "content": "include ':app'\n\ndef flutterProjectRoot = rootProject.projectDir.parentFile.toPath()\n\ndef plugins = new Properties()\ndef pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')\nif (pluginsFile.exists()) {\n    pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }\n}\n\nplugins.each { name, path ->\n    def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()\n    include \":$name\"\n    project(\":$name\").projectDir = pluginDirectory\n}\n"
  },
  {
    "path": "example/android/settings_aar.gradle",
    "content": "include ':app'\n"
  },
  {
    "path": "example/lib/main.dart",
    "content": "import 'dart:async';\n\nimport 'package:floaty_head/floaty_head.dart';\nimport 'package:flutter/material.dart';\nimport 'package:flutter/services.dart';\n\nFuture<void> main() async {\n  runApp(MaterialApp(home: Home()));\n}\n\nclass Home extends StatefulWidget {\n  _Home createState() => _Home();\n}\n\nclass _Home extends State<Home> {\n  final FloatyHead floatyHead = FloatyHead();\n\n  final header = FloatyHeadHeader(\n    title: FloatyHeadText(\n      text: \"Outgoing Call\",\n      fontSize: 10,\n      textColor: Colors.black45,\n      fontWeight: FontWeight.normal,\n      padding: FloatyHeadPadding(\n        bottom: 4,\n        left: 5,\n        right: 5,\n        top: 5,\n      ),\n    ),\n    padding: FloatyHeadPadding.setSymmetricPadding(12, 12),\n    subTitle: FloatyHeadText(\n      text: \"8989898989\",\n      fontSize: 14,\n      fontWeight: FontWeight.bold,\n      padding: FloatyHeadPadding(\n        bottom: 4,\n        left: 5,\n        right: 5,\n        top: 5,\n      ),\n      textColor: Colors.black87,\n    ),\n    decoration: FloatyHeadDecoration(startColor: Colors.grey[100]),\n    button: FloatyHeadButton(\n        text: FloatyHeadText(\n          fontWeight: FontWeight.bold,\n          text: \"Personal\",\n          fontSize: 10,\n          textColor: Colors.black45,\n          padding: FloatyHeadPadding(\n            bottom: 4,\n            left: 5,\n            right: 5,\n            top: 5,\n          ),\n        ),\n        tag: \"personal_btn\"),\n  );\n\n  final body = FloatyHeadBody(\n    rows: [\n      EachRow(\n        columns: [\n          EachColumn(\n            text: FloatyHeadText(\n              fontWeight: FontWeight.bold,\n              text: \"Updated body\",\n              fontSize: 12,\n              textColor: Colors.black45,\n              padding: FloatyHeadPadding(\n                bottom: 4,\n                left: 5,\n                right: 5,\n                top: 5,\n              ),\n            ),\n          ),\n        ],\n        gravity: ContentGravity.center,\n      ),\n      EachRow(columns: [\n        EachColumn(\n          text: FloatyHeadText(\n            text: \"Updated long data of the body\",\n            fontSize: 12,\n            textColor: Colors.black87,\n            fontWeight: FontWeight.bold,\n            padding: FloatyHeadPadding(\n              bottom: 4,\n              left: 5,\n              right: 5,\n              top: 5,\n            ),\n          ),\n          padding: FloatyHeadPadding.setSymmetricPadding(6, 8),\n          decoration: FloatyHeadDecoration(\n              startColor: Colors.black12, borderRadius: 25.0),\n          margin: FloatyHeadMargin(top: 4),\n        ),\n      ], gravity: ContentGravity.center),\n      EachRow(\n        columns: [\n          EachColumn(\n            text: FloatyHeadText(\n              text: \"Notes\",\n              fontSize: 10,\n              textColor: Colors.black45,\n              fontWeight: FontWeight.normal,\n              padding: FloatyHeadPadding(\n                bottom: 4,\n                left: 5,\n                right: 5,\n                top: 5,\n              ),\n            ),\n          ),\n        ],\n        gravity: ContentGravity.left,\n        margin: FloatyHeadMargin(top: 8),\n      ),\n      EachRow(\n        columns: [\n          EachColumn(\n            text: FloatyHeadText(\n              text: \"Updated random notes.\",\n              fontSize: 13,\n              textColor: Colors.black54,\n              fontWeight: FontWeight.bold,\n              padding: FloatyHeadPadding(\n                bottom: 4,\n                left: 5,\n                right: 5,\n                top: 5,\n              ),\n            ),\n          ),\n        ],\n        gravity: ContentGravity.left,\n      ),\n    ],\n    padding: FloatyHeadPadding(left: 16, right: 16, bottom: 12, top: 12),\n  );\n\n  final footer = FloatyHeadFooter(\n    buttons: [\n      FloatyHeadButton(\n        text: FloatyHeadText(\n          text: \"Simple button\",\n          fontSize: 12,\n          textColor: Color.fromRGBO(250, 139, 97, 1),\n          padding: FloatyHeadPadding(\n            bottom: 4,\n            left: 5,\n            right: 5,\n            top: 5,\n          ),\n          fontWeight: FontWeight.normal,\n        ),\n        tag: \"simple_button\",\n        padding: FloatyHeadPadding(left: 10, right: 10, bottom: 10, top: 10),\n        width: 0,\n        height: FloatyHeadButton.WRAP_CONTENT,\n        decoration: FloatyHeadDecoration(\n            startColor: Colors.white,\n            endColor: Colors.white,\n            borderWidth: 0,\n            borderRadius: 0.0),\n      ),\n      FloatyHeadButton(\n        text: FloatyHeadText(\n          fontWeight: FontWeight.normal,\n          padding: FloatyHeadPadding(\n            bottom: 4,\n            left: 5,\n            right: 5,\n            top: 5,\n          ),\n          text: \"Focus button\",\n          fontSize: 12,\n          textColor: Colors.white,\n        ),\n        tag: \"focus_button\",\n        width: 0,\n        padding: FloatyHeadPadding(left: 10, right: 10, bottom: 10, top: 10),\n        height: FloatyHeadButton.WRAP_CONTENT,\n        decoration: FloatyHeadDecoration(\n            startColor: Color.fromRGBO(250, 139, 97, 1),\n            endColor: Color.fromRGBO(247, 28, 88, 1),\n            borderWidth: 0,\n            borderRadius: 30.0),\n      )\n    ],\n    padding: FloatyHeadPadding(left: 16, right: 16, bottom: 12),\n    decoration: FloatyHeadDecoration(startColor: Colors.white),\n    buttonsPosition: ButtonPosition.center,\n  );\n\n  bool alternateColor = false;\n\n  @override\n  void initState() {\n    super.initState();\n    FloatyHead.registerOnClickListener(callBack);\n  }\n\n  @override\n  Widget build(BuildContext context) => Scaffold(\n        appBar: AppBar(title: Text('Floaty Chathead')),\n        body: SingleChildScrollView(\n          padding: EdgeInsets.all(50),\n          child: Column(\n            mainAxisAlignment: MainAxisAlignment.center,\n            crossAxisAlignment: CrossAxisAlignment.stretch,\n            children: [\n              ElevatedButton(\n                  child: Text('Open Floaty Chathead'),\n                  onPressed: () => floatyHead.openBubble()),\n              ElevatedButton(\n                  child: Text('Close Floaty Chathead'),\n                  onPressed: () => closeFloatyHead()),\n              ElevatedButton(\n                  child: Text('Set icon Floaty Chathead'),\n                  onPressed: () => setIcon()),\n              ElevatedButton(\n                  child: Text('Set close icon Floaty Chathead'),\n                  onPressed: () => setCloseIcon()),\n              ElevatedButton(\n                  child: Text('Set close background Icon Floaty Chathead'),\n                  onPressed: () => setCloseIconBackground()),\n              ElevatedButton(\n                  child: Text(\n                      'Set notification title to: OH MY GOD! THEY KILL KENNY!!! Floaty Chathead'),\n                  onPressed: () => setNotificationTitle()),\n              ElevatedButton(\n                  child: Text('Set notification Icon Floaty Chathead'),\n                  onPressed: () => setNotificationIcon()),\n              ElevatedButton(\n                  child: Text('Set Custom Header into Floaty Chathead'),\n                  onPressed: () => setCustomHeader()),\n            ],\n          ),\n        ),\n      );\n\n  void setCustomHeader() {\n    floatyHead.updateFloatyHeadContent(\n      header: header,\n      body: body,\n      footer: footer,\n    );\n  }\n\n  void closeFloatyHead() {\n    if (floatyHead.isOpen) {\n      floatyHead.closeHead();\n    }\n  }\n\n  Future<void> setNotificationTitle() async {\n    String result;\n    try {\n      result = await floatyHead\n          .setNotificationTitle(\"OH MY GOD! THEY KILL KENNY!!!\");\n    } on PlatformException {\n      result = 'Failed to get icon.';\n    }\n    print('result: $result');\n    if (!mounted) return;\n  }\n\n  Future<void> setNotificationIcon() async {\n    String result;\n    String assetPath = \"assets/notificationIcon.png\";\n    try {\n      result = await floatyHead.setNotificationIcon(assetPath);\n      print(result);\n    } on PlatformException {\n      result = 'Failed to get icon.';\n      print(\"failed: $result\");\n    }\n    if (!mounted) return;\n  }\n\n  Future<void> setIcon() async {\n    String result;\n    String assetPath = \"assets/chatheadIcon.png\";\n    try {\n      result = await floatyHead.setIcon(assetPath);\n      print('result: $result');\n    } on PlatformException {\n      result = 'Failed to get icon.';\n    }\n    if (!mounted) return;\n  }\n\n  Future<void> setCloseIcon() async {\n    String assetPath = \"assets/close.png\";\n    try {\n      await floatyHead.setCloseIcon(assetPath);\n    } on PlatformException {\n      return;\n    }\n    if (!mounted) return;\n  }\n\n  Future<void> setCloseIconBackground() async {\n    String assetPath = \"assets/closeBg.png\";\n    try {\n      await floatyHead.setCloseBackgroundIcon(assetPath);\n    } on PlatformException {\n      return;\n    }\n    if (!mounted) return;\n  }\n}\n\nvoid callBack(String tag) {\n  print('CALLBACK FROM FRAGMENT BUILDED: $tag');\n  switch (tag) {\n    case \"simple_button\":\n    case \"updated_simple_button\":\n      break;\n    case \"focus_button\":\n      print(\"Focus button has been called\");\n      break;\n    default:\n      print(\"OnClick event of $tag\");\n  }\n}\n"
  },
  {
    "path": "example/pubspec.yaml",
    "content": "name: floaty_head_example\ndescription: Demonstrates how to use the floaty_head plugin.\n\n# The following line prevents the package from being accidentally published to\n# pub.dev using `pub publish`. This is preferred for private packages.\npublish_to: 'none' # Remove this line if you wish to publish to pub.dev\n\nenvironment:\n  sdk: \">=2.1.0 <3.0.0\"\n\ndependencies:\n  flutter:\n    sdk: flutter\n\n  # The following adds the Cupertino Icons font to your application.\n  # Use with the CupertinoIcons class for iOS style icons.\n  cupertino_icons: ^0.1.3\n\ndev_dependencies:\n  flutter_test:\n    sdk: flutter\n  floaty_head:\n    path: ../\n\n# For information on the generic Dart part of this file, see the\n# following page: https://dart.dev/tools/pub/pubspec\n\n# The following section is specific to Flutter.\nflutter:\n\n  # The following line ensures that the Material Icons font is\n  # included with your application, so that you can use the icons in\n  # the material Icons class.\n  uses-material-design: true\n\n  # To add assets to your application, add an assets section, like this:\n  # assets:\n  #   - images/a_dot_burr.jpeg\n  #   - images/a_dot_ham.jpeg\n  assets:\n    - assets/chatheadIcon.png\n    - assets/close.png\n    - assets/closeBg.png\n    - assets/notificationIcon.png\n  # An image asset can refer to one or more resolution-specific \"variants\", see\n  # https://flutter.dev/assets-and-images/#resolution-aware.\n\n  # For details regarding adding assets from package dependencies, see\n  # https://flutter.dev/assets-and-images/#from-packages\n\n  # To add custom fonts to your application, add a fonts section here,\n  # in this \"flutter\" section. Each entry in this list should have a\n  # \"family\" key with the font family name, and a \"fonts\" key with a\n  # list giving the asset and other descriptors for the font. For\n  # example:\n  # fonts:\n  #   - family: Schyler\n  #     fonts:\n  #       - asset: fonts/Schyler-Regular.ttf\n  #       - asset: fonts/Schyler-Italic.ttf\n  #         style: italic\n  #   - family: Trajan Pro\n  #     fonts:\n  #       - asset: fonts/TrajanPro.ttf\n  #       - asset: fonts/TrajanPro_Bold.ttf\n  #         weight: 700\n  #\n  # For details regarding fonts from package dependencies,\n  # see https://flutter.dev/custom-fonts/#from-packages\n"
  },
  {
    "path": "example/test/widget_test.dart",
    "content": "// This is a basic Flutter widget test.\n//\n// To perform an interaction with a widget in your test, use the WidgetTester\n// utility that Flutter provides. For example, you can send tap and scroll\n// gestures. You can also use WidgetTester to find child widgets in the widget\n// tree, read text, and verify that the values of widget properties are correct.\n\nimport 'package:flutter/material.dart';\nimport 'package:flutter_test/flutter_test.dart';\n\nimport 'package:floaty_head_example/main.dart';\n\nvoid main() {\n  testWidgets('Verify Platform version', (WidgetTester tester) async {\n    // Build our app and trigger a frame.\n    await tester.pumpWidget(Home());\n\n    // Verify that platform version is retrieved.\n    expect(\n      find.byWidgetPredicate(\n        (Widget widget) =>\n            widget is Text && widget.data.startsWith('Running on:'),\n      ),\n      findsOneWidget,\n    );\n  });\n}\n"
  },
  {
    "path": "floaty_head.iml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module type=\"JAVA_MODULE\" version=\"4\">\n  <component name=\"NewModuleRootManager\" inherit-compiler-output=\"true\">\n    <exclude-output />\n    <content url=\"file://$MODULE_DIR$\">\n      <sourceFolder url=\"file://$MODULE_DIR$/lib\" isTestSource=\"false\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/.dart_tool\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/.idea\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/.pub\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/example/.dart_tool\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/example/.pub\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/example/build\" />\n    </content>\n    <orderEntry type=\"sourceFolder\" forTests=\"false\" />\n    <orderEntry type=\"library\" name=\"Dart SDK\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Flutter Plugins\" level=\"project\" />\n  </component>\n</module>"
  },
  {
    "path": "lib/floaty_head.dart",
    "content": "import 'dart:async';\nimport 'dart:io';\nimport 'dart:ui';\n\nexport 'models/floaty_head_body.dart';\nexport 'models/floaty_head_button.dart';\nexport 'models/floaty_head_decoration.dart';\nexport 'models/floaty_head_footer.dart';\nexport 'models/floaty_head_header.dart';\nexport 'models/floaty_head_margin.dart';\nexport 'models/floaty_head_padding.dart';\nexport 'models/floaty_head_text.dart';\nexport 'utils/commons.dart';\n\nimport 'package:floaty_head/models/floaty_head_body.dart';\nimport 'package:floaty_head/models/floaty_head_footer.dart';\nimport 'package:floaty_head/models/floaty_head_header.dart';\nimport 'package:floaty_head/models/floaty_head_margin.dart';\nimport 'package:flutter/services.dart';\nimport 'package:flutter/widgets.dart';\n\n/// Set the [gravity] orientation for the header of the chathead\n///\n/// use [top] to position the content of the header\n/// to the upper side of the container.\n///\n/// use [bottom] to position the content of the header\n/// to the bottom side of the container.\n///\n/// use [center] to position the content of the header\n/// to the bottom side of the container.\nenum FloatyHeadGravity {\n  top,\n  bottom,\n  center,\n}\n\n/// Set the [gravity] orientation for the body of the chathead\n///\n/// use [left] to position the content of the body\n/// to the Start side of the container.\n///\n/// use [right] to position the content of the body\n/// to the End side of the container.\n///\n/// use [center] to position the content of the body\n/// to the center of the container.\nenum ContentGravity {\n  left,\n  right,\n  center,\n}\n\n/// Set the [position] for the buttons of the chathead\n///\n/// use [trailing] to position the button\n/// at the End of the container.\n///\n/// use [leading] to position the button\n/// at the Start of the container.\n///\n/// use [center] to position the button\n/// at the center of the container.\nenum ButtonPosition {\n  trailing,\n  leading,\n  center,\n}\n\n/// Set the [Weight] for the text inside the chathead\n///\n/// use [normal] for w500 font.\n///\n/// use [bold] for w900 font.\n///\n/// use [italic] for a stylished font.\n///\n/// use [bold_italic] for a w900 font with stylished.\nenum FontWeight {\n  normal,\n  bold,\n  italic,\n  bold_italic,\n}\n\n/// This is called when a button is tapped, the return is gonna be.\n/// ```dart\n/// OnClickListener(String tag) => 'btn_ok';\n/// ```\ntypedef void OnClickListener(String tag);\n\nclass FloatyHead {\n  bool _isOpen = false;\n  Timer? _callback;\n  late Timer _timer;\n\n  /// Return the [state] of the chathead\n  /// ```dart\n  /// bool get isOpen => true or false;\n  /// ```\n  bool get isOpen => _isOpen;\n\n  /// The timer is used when an action is needed to perform after x time has passed.\n  Timer? get callback => _callback;\n  static const _platform = const MethodChannel('ni.devotion/floaty_head');\n\n  FloatyHead() {\n    if (!Platform.isAndroid)\n      throw PlatformException(code: 'Floaty Head only available for Android');\n  }\n\n  /// Start the chathead.\n  /// also check constantly the current state of it.\n  ///\n  /// for that please use the method [isOpen].\n  void openBubble() async {\n    _platform.invokeMethod('start');\n    _timer = Timer.periodic(Duration(seconds: 1), (timer) async {\n      _isOpen = await _platform.invokeMethod('isOpen') ?? false;\n      if (!_isOpen) {\n        timer.cancel();\n      }\n    });\n  }\n\n  /// If a [widget] is [pressed] check the [type] of [tap].\n  /// and returns to the client-dart the component that has been pressed as a\n  /// [string] with his tag.\n  static Future<bool> registerOnClickListener(\n      OnClickListener callBackFunction) async {\n    final callBackDispatcher =\n        PluginUtilities.getCallbackHandle(callbackDispatcher)!;\n    final callBack = PluginUtilities.getCallbackHandle(callBackFunction)!;\n    _platform.setMethodCallHandler((MethodCall call) {\n      switch (call.method) {\n        case \"callBack\":\n          dynamic arguments = call.arguments;\n          if (arguments is List) {\n            final type = arguments[0];\n            if (type == \"onClick\") {\n              final tag = arguments[1];\n              callBackFunction(tag);\n            }\n          }\n      }\n      return null;\n    } as Future<dynamic> Function(MethodCall)?);\n    await _platform.invokeMethod(\"registerCallBackHandler\",\n        <dynamic>[callBackDispatcher.toRawHandle(), callBack.toRawHandle()]);\n    return true;\n  }\n\n  ///Set a custom [icon] for the chathead.\n  Future<String> setIcon(String assetPath) async {\n    final int result =\n        await (_platform.invokeMethod('setIcon', assetPath) as FutureOr<int>);\n    return result > 0 ? \"Icon set\" : \"There was an error.\";\n  }\n\n  ///Set a custom [Title] to be displayed in the notification bar for the chathead.\n  Future<String> setNotificationTitle(String title) async {\n    final int result = await (_platform.invokeMethod(\n        'setNotificationTitle', title) as FutureOr<int>);\n    return result > 0 ? \"Notification Title set\" : \"There was an error.\";\n  }\n\n  /// Set a custom [IconTitle] to be displayed in the notification bar for the chathead.\n  /// Please note that in some cases, this is gonna ignore any asset given, and instead\n  /// use the default icon launcher.\n  Future<String> setNotificationIcon(String assetPath) async {\n    final int result = await (_platform.invokeMethod(\n        'setNotificationIcon', assetPath) as FutureOr<int>);\n    return result > 0 ? \"NotificationIcon set\" : \"There was an error.\";\n  }\n\n  /// Set a custom [Close Icon] to be displayed when the chathead is dragged.\n  Future<String> setCloseIcon(String assetPath) async {\n    final int result = await (_platform.invokeMethod('setCloseIcon', assetPath)\n        as FutureOr<int>);\n    return result > 0 ? \"Close Icon set\" : \"There was an error.\";\n  }\n\n  /// Set a custom [Close Background] to be displayed behind the [Close Icon].\n  Future<String> setCloseBackgroundIcon(String assetPath) async {\n    final int result = await (_platform.invokeMethod(\n        'setBackgroundCloseIcon', assetPath) as FutureOr<int>);\n    return result > 0 ? \"Close Icon Background set\" : \"There was an error.\";\n  }\n\n  /// Close the [chathead].\n  void closeHead() {\n    if (_isOpen) {\n      _platform.invokeMethod('close');\n      _timer.cancel();\n      _isOpen = false;\n    } else\n      throw Exception('Floaty Head not running');\n  }\n\n  /// This functions updates all the UI that is builded in the custom layout\n  /// that the chathead uses.\n  Future<bool?> updateFloatyHeadContent({\n    required FloatyHeadHeader header,\n    FloatyHeadBody? body,\n    FloatyHeadFooter? footer,\n    FloatyHeadMargin? margin,\n    int? width,\n    int? height,\n  }) async {\n    final Map<String, dynamic> params = <String, dynamic>{\n      'header': header.getMap(),\n      'body': body?.getMap(),\n      'footer': footer?.getMap(),\n      'margin': margin?.getMap(),\n      'gravity': 1.0,\n      'width': width ?? -1,\n      'height': height ?? -2\n    };\n    return await _platform.invokeMethod('setFloatyHeadContent', params);\n  }\n}\n\n/// Notify to the sender/caller that a widget has been pressed.\nvoid callbackDispatcher() {\n  const MethodChannel _backgroundChannel =\n      const MethodChannel('ni.devotion.floaty_head/background');\n  WidgetsFlutterBinding.ensureInitialized();\n  _backgroundChannel.setMethodCallHandler((MethodCall call) async {\n    final args = call.arguments;\n    final Function callback = PluginUtilities.getCallbackFromHandle(\n        CallbackHandle.fromRawHandle(args[0]))!;\n    final type = args[1];\n    if (type == \"onClick\") {\n      final tag = args[2];\n      callback(tag);\n    }\n  });\n}\n"
  },
  {
    "path": "lib/models/floaty_head_body.dart",
    "content": "import 'package:floaty_head/floaty_head.dart';\n\n/// This class is used to build the [Body] that is gonna be displayed\n/// when the chathead is tapped.\nclass FloatyHeadBody {\n  List<EachRow>? rows;\n  FloatyHeadPadding? padding;\n  FloatyHeadDecoration? decoration;\n\n  ///[FloatyHeadBody] currently accepts multiple rows, padding and decoration.\n  ///in case of a new components.\n  ///\n  ///ex: columns\n  ///please add it to this segment.\n  FloatyHeadBody({\n    this.rows,\n    this.padding,\n    this.decoration,\n  });\n\n  /// Map the data obtained from the dart-client.\n  Map<String, dynamic> getMap() {\n    final Map<String, dynamic> map = <String, dynamic>{\n      'rows': (rows == null)\n          ? null\n          : List<dynamic>.from(rows!.map((x) => x.getMap())),\n      'padding': padding?.getMap(),\n      'decoration': decoration?.getMap()\n    };\n    return map;\n  }\n}\n\n/// This class is used to build the [Row Content] inside the [Body] that is gonna be displayed\n/// when the chathead is tapped.\nclass EachRow {\n  List<EachColumn>? columns;\n  FloatyHeadPadding? padding;\n  FloatyHeadMargin? margin;\n  ContentGravity? gravity;\n  FloatyHeadDecoration? decoration;\n\n  EachRow({\n    this.columns,\n    this.padding,\n    this.margin,\n    this.gravity,\n    this.decoration,\n  });\n\n  Map<String, dynamic> getMap() {\n    final Map<String, dynamic> map = <String, dynamic>{\n      'columns': (columns == null)\n          ? null\n          : List<dynamic>.from(columns!.map((x) => x.getMap())),\n      'padding': padding?.getMap(),\n      'margin': margin?.getMap(),\n      'gravity': Commons.getContentGravity(gravity),\n      'decoration': decoration?.getMap(),\n    };\n    return map;\n  }\n}\n\n/// This class is used to build the [Column Content] inside the [Body] that is gonna be displayed\n/// when the chathead is tapped.\nclass EachColumn {\n  FloatyHeadText? text;\n  FloatyHeadPadding? padding;\n  FloatyHeadMargin? margin;\n  FloatyHeadDecoration? decoration;\n\n  EachColumn({\n    this.text,\n    this.padding,\n    this.margin,\n    this.decoration,\n  });\n\n  Map<String, dynamic> getMap() {\n    final Map<String, dynamic> map = <String, dynamic>{\n      'text': text?.getMap(),\n      'padding': padding?.getMap(),\n      'margin': margin?.getMap(),\n      'decoration': decoration?.getMap()\n    };\n    return map;\n  }\n}\n"
  },
  {
    "path": "lib/models/floaty_head_button.dart",
    "content": "import 'package:floaty_head/floaty_head.dart';\n\n/// This class is used to build the [Buttons] inside the [Body] that is gonna be displayed\n/// when the chathead is tapped.\nclass FloatyHeadButton {\n  static const int MATCH_PARENT = -1;\n  static const int WRAP_CONTENT = -2;\n  FloatyHeadText text;\n  FloatyHeadPadding? padding;\n  FloatyHeadMargin? margin;\n  FloatyHeadDecoration? decoration;\n  int? width;\n  int? height;\n  String tag;\n\n  FloatyHeadButton({\n    required this.text,\n    required this.tag,\n    this.padding,\n    this.margin,\n    this.width,\n    this.height,\n    this.decoration,\n  });\n\n  Map<String, dynamic> getMap() {\n    final Map<String, dynamic> map = <String, dynamic>{\n      'text': text.getMap(),\n      'tag': tag,\n      'padding': padding?.getMap(),\n      'margin': margin?.getMap(),\n      'width': width ?? WRAP_CONTENT,\n      'height': height ?? WRAP_CONTENT,\n      'decoration': decoration?.getMap()\n    };\n    return map;\n  }\n}\n"
  },
  {
    "path": "lib/models/floaty_head_decoration.dart",
    "content": "import 'package:flutter/material.dart';\n\n/// This class is used to build the [Decoration] inside the [Body] that is gonna be displayed\n/// when the chathead is tapped.\nclass FloatyHeadDecoration {\n  Color? startColor;\n  Color? endColor;\n  int? borderWidth;\n  double? borderRadius;\n  Color? borderColor;\n\n  FloatyHeadDecoration({\n    this.startColor,\n    this.endColor,\n    this.borderWidth,\n    this.borderRadius,\n    this.borderColor,\n  });\n\n  Map<String, dynamic> getMap() {\n    final Map<String, dynamic> map = <String, dynamic>{\n      'startColor': startColor?.value ?? Colors.white.value,\n      'endColor': endColor?.value,\n      'borderWidth': borderWidth ?? 0,\n      'borderRadius': borderRadius ?? 0.0,\n      'borderColor': borderColor?.value ?? Colors.white.value\n    };\n    return map;\n  }\n}\n"
  },
  {
    "path": "lib/models/floaty_head_footer.dart",
    "content": "import 'package:floaty_head/floaty_head.dart';\n\n/// This class is used to build the [Footer Content] inside the [Body] that is gonna be displayed\n/// when the chathead is tapped.\nclass FloatyHeadFooter {\n  FloatyHeadText? text;\n  FloatyHeadPadding? padding;\n  List<FloatyHeadButton>? buttons;\n  ButtonPosition? buttonsPosition;\n  FloatyHeadDecoration? decoration;\n\n  FloatyHeadFooter({\n    this.text,\n    this.padding,\n    this.buttons,\n    this.buttonsPosition,\n    this.decoration,\n  });\n\n  Map<String, dynamic> getMap() {\n    final Map<String, dynamic> map = <String, dynamic>{\n      'isShowFooter': (text != null || (buttons != null && buttons!.length > 0)),\n      'text': text?.getMap(),\n      'buttons': (buttons == null)\n          ? null\n          : List<Map<String, dynamic>>.from(\n              buttons!.map((button) => button.getMap())),\n      'buttonsPosition': Commons.getPosition(buttonsPosition),\n      'padding': padding?.getMap(),\n      'decoration': decoration?.getMap()\n    };\n    return map;\n  }\n}\n"
  },
  {
    "path": "lib/models/floaty_head_header.dart",
    "content": "import 'package:floaty_head/floaty_head.dart';\nimport 'package:flutter/material.dart';\n\n/// This class is used to build the [Header Content] inside the [Body] that is gonna be displayed\n/// when the chathead is tapped.\nclass FloatyHeadHeader {\n  @required\n  FloatyHeadText? title;\n  FloatyHeadText? subTitle;\n  FloatyHeadButton? button;\n  ButtonPosition? buttonsPosition;\n  FloatyHeadPadding? padding;\n  FloatyHeadDecoration? decoration;\n\n  FloatyHeadHeader({\n    this.title,\n    this.subTitle,\n    this.button,\n    this.buttonsPosition,\n    this.padding,\n    this.decoration,\n  });\n\n  Map<String, dynamic> getMap() {\n    final Map<String, dynamic> map = <String, dynamic>{\n      'title': title?.getMap(),\n      'subTitle': subTitle?.getMap(),\n      'button': button?.getMap(),\n      'padding': padding?.getMap(),\n      'buttonPosition': Commons.getPosition(buttonsPosition),\n      'decoration': decoration?.getMap()\n    };\n    return map;\n  }\n}\n"
  },
  {
    "path": "lib/models/floaty_head_margin.dart",
    "content": "/// This class is used to build the [Margin] inside the [Body] that is gonna be displayed\n/// when the chathead is tapped.\nclass FloatyHeadMargin {\n  int? left;\n  int? right;\n  int? top;\n  int? bottom;\n\n  FloatyHeadMargin({this.left, this.right, this.top, this.bottom});\n\n  Map<String, int> getMap() {\n    final Map<String, int> map = <String, int>{\n      'left': left ?? 0,\n      'right': right ?? 0,\n      'top': top ?? 0,\n      'bottom': bottom ?? 0,\n    };\n    return map;\n  }\n\n  static FloatyHeadMargin setSymmetricMargin(int vertical, int horizontal) {\n    return FloatyHeadMargin(\n      left: horizontal,\n      right: horizontal,\n      top: vertical,\n      bottom: vertical,\n    );\n  }\n}\n"
  },
  {
    "path": "lib/models/floaty_head_padding.dart",
    "content": "/// This class is used to build the [Padding] inside the [Body] that is gonna be displayed\n/// when the chathead is tapped.\nclass FloatyHeadPadding {\n  int? left;\n  int? right;\n  int? top;\n  int? bottom;\n\n  FloatyHeadPadding({this.left, this.right, this.top, this.bottom});\n\n  Map<String, int> getMap() {\n    final Map<String, int> map = <String, int>{\n      'left': left ?? 0,\n      'right': right ?? 0,\n      'top': top ?? 0,\n      'bottom': bottom ?? 0,\n    };\n    return map;\n  }\n\n  static FloatyHeadPadding setSymmetricPadding(int vertical, int horizontal) {\n    return FloatyHeadPadding(\n      left: horizontal,\n      right: horizontal,\n      top: vertical,\n      bottom: vertical,\n    );\n  }\n}\n"
  },
  {
    "path": "lib/models/floaty_head_text.dart",
    "content": "import 'package:floaty_head/floaty_head.dart';\nimport 'package:flutter/material.dart';\n\n/// This class is used to build any [Text] inside the [Body] that is gonna be displayed\n/// when the chathead is tapped.\nclass FloatyHeadText {\n  String text;\n  double fontSize;\n  Color textColor;\n  FontWeight fontWeight;\n  FloatyHeadPadding padding;\n\n  FloatyHeadText(\n      {required this.text,\n      /*required*/ required this.fontSize,\n      /*required*/ required this.fontWeight,\n      /*required*/ required this.textColor,\n      /*required*/ required this.padding});\n\n  Map<String, dynamic> getMap() {\n    final Map<String, dynamic> map = <String, dynamic>{\n      'text': text,\n      'fontSize': fontSize,\n      'fontWeight': Commons.getFontWeight(fontWeight),\n      'textColor': textColor.value,\n      'padding': padding.getMap(),\n    };\n    return map;\n  }\n}\n"
  },
  {
    "path": "lib/utils/commons.dart",
    "content": "import 'package:floaty_head/floaty_head.dart';\n\nclass Commons {\n  /// Replace the [windowGravity] setted in dart-client code.\n  static String getWindowGravity(FloatyHeadGravity? gravity) {\n    if (gravity == null) gravity = FloatyHeadGravity.top;\n    switch (gravity) {\n      case FloatyHeadGravity.center:\n        return \"center\";\n      case FloatyHeadGravity.bottom:\n        return \"bottom\";\n      case FloatyHeadGravity.top:\n      default:\n        return \"top\";\n    }\n  }\n\n  /// Replace the [contentGravity] setted in dart-client code.\n  static String getContentGravity(ContentGravity? gravity) {\n    if (gravity == null) gravity = ContentGravity.left;\n    switch (gravity) {\n      case ContentGravity.center:\n        return \"center\";\n      case ContentGravity.right:\n        return \"right\";\n      case ContentGravity.left:\n      default:\n        return \"left\";\n    }\n  }\n\n  /// Replace the [position] setted in dart-client code.\n  static String getPosition(ButtonPosition? buttonPosition) {\n    if (buttonPosition == null) buttonPosition = ButtonPosition.center;\n    switch (buttonPosition) {\n      case ButtonPosition.leading:\n        return \"leading\";\n      case ButtonPosition.trailing:\n        return \"trailing\";\n      case ButtonPosition.center:\n      default:\n        return \"center\";\n    }\n  }\n\n  /// Replace the [fontWeight] setted in dart-client code.\n  static String getFontWeight(FontWeight? fontWeight) {\n    if (fontWeight == null) fontWeight = FontWeight.normal;\n    switch (fontWeight) {\n      case FontWeight.bold:\n        return \"bold\";\n      case FontWeight.italic:\n        return \"italic\";\n      case FontWeight.bold_italic:\n        return \"bold_italic\";\n      case FontWeight.normal:\n      default:\n        return \"normal\";\n    }\n  }\n}\n"
  },
  {
    "path": "pubspec.yaml",
    "content": "name: floaty_head\ndescription: A flutter plugin to create custom chatheads with hidden content displayed on tap, like Messenger.\nversion: 2.0.0-nullsafety.0\nhomepage: https://github.com/Crdzbird/floaty_chathead\n\nenvironment:\n  sdk: '>=2.12.0 <3.0.0'\n  flutter: \">=1.20.0\"\n\ndependencies:\n  flutter:\n    sdk: flutter\n\ndev_dependencies:\n  flutter_test:\n    sdk: flutter\n\nflutter:\n  plugin:\n    platforms:\n      android:\n        package: ni.devotion.floaty_head\n        pluginClass: FloatyHeadPlugin\n      ios:\n        pluginClass: FloatyHeadPlugin"
  },
  {
    "path": "test/floaty_head_test.dart",
    "content": "import 'package:flutter/services.dart';\nimport 'package:flutter_test/flutter_test.dart';\n\nvoid main() {\n  const MethodChannel channel = MethodChannel('floaty_head');\n\n  TestWidgetsFlutterBinding.ensureInitialized();\n\n  setUp(() {\n    channel.setMockMethodCallHandler((MethodCall methodCall) async {\n      return '42';\n    });\n  });\n\n  tearDown(() {\n    channel.setMockMethodCallHandler(null);\n  });\n}\n"
  }
]