[
  {
    "path": ".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.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.dart_tool/\n.flutter-plugins\n.packages\n.pub-cache/\n.pub/\n/build/\n\n# Web related\nlib/generated_plugin_registrant.dart\n\n# Exceptions to above rules.\n!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages\npubspec.lock\nexample/.flutter-plugins-dependencies\nexample/pubspec.lock\n.flutter-plugins-dependencies\n/.fvm/\n"
  },
  {
    "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: 2c7af1e24e45a79f4eb73d67d98fcecea8bf6146\n  channel: master\n\nproject_type: plugin\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "## 0.3.4\n- Finalised release of 0.3.3-null-safety+2 with Null-safety, Material 3 & flutter 3 changes\n- Huge thanks to @nyxkn for all fixes & updates for this release\n- Huge thanks to @romanbsd for all updates to Flutter 3 changes\n\n\n## 0.3.3-null-safety+2\n - add flag to enable textfield content to be autoselected on focus\n - change capitalization of autovalidateMode\n - TextInput: expose helperText and inputFormatters\n - fix: null-safety warning messages\n - fix: valuechangeobserver dispose accidentally clears the whole _notifier map rather than just its own cachekey\n - Huge thanks to @nyxkn for all fixes & updates for this release\n\n## 0.3.3-null-safety+1\n - Fix issue where implementation for setObject in default cache provider always throws exception\n - Custom text style in all widgets\n - Clear the notifiers map when the widget is disposed\n\n## 0.3.3-null-safety\n - Breaking Changes:\n   - Cache Provider interface definition updated to allow asynchronous getter/setter\n   - Optional Default values are moved to getters instead of setters\n   - Flutter SDK version upgraded to 2.15.0 & upgraded the plugin dependencies\n   - Changed all getters & setters definitions to support null values\n   - Changed Settings implementation according to new changes\n - Example app moved Flutter SDK to 2.15.0\n - Updated example app implementation\n - Updated Code documentation in cache provider interface\n\n\n## 0.3.2-null-safety\n - Provider version updated to 6.0.0, thanks to @Pawelek55\n - ExpandedSettingTile were not using the provided expanded status, fixed by @Colton127\n - Updated theme changes in the source code & in the example to resolve analyzer warnings\n\n## 0.3.1-null-safety\n - added functionality to update the specific SettingsUI by updating it's value\n   by calling setValue with `notify` as `true`.\n\n   Example:\n   ```dart\n    await Settings.setValue<T>(cacheKey, newValue, notify: true);\n   ```\n\n - Fix - Unresponsive tapping of the switch tile, fixed by @pascalwils\n - Updated ReadMe content to match new updates\n - Updated example app code to demo the UI update functionality\n    - Checkout Auto adjusting Volume slider\n\n## 0.3.0-null-safety\n - null-safety migration\n - bug-fix for slider not respecting step value in decimal points\n\n## 0.2.2+1\n - complete dependency update to latest\n\n## 0.2.2\n - remove autovalidate option to comply with new sdk changes\n - remove unnecessary use of Generic cache provider interface\n    `Set<E> getKeys<E>()` -> `Set getKeys()`\n\t- reason for this is that generics may restrict some implementation in some way\n\t- to achieve the same effect as the generics implementation, one can just `cast` the set as they want\n\t- if the whole interface depends on generics only then the previous declaration makes sense.\n - update & fix example app code\n - plugin code organization & documentation updates\n\n#### Developer Note:\n  1. The sdk upgrade will be done in two stages\n    - stage 1: only update the dependencies with code changes to comply with the updates\n\t- stage 2: update the flutter/dart sdk version along with the least version of supported dependencies\n  2. Few of the next releases may contain some breaking changes in relation to cache provider implementation\n  3. A few of the planned updates:\n      - null safety support for library\n      - cache provider structuring to support universal implementation, allows using any storage platform to be used\n\t    like, shared_preferences, hive, flutter_secure_storage, etc\n\t  - massive UI customization in terms of platforms & designs\n\t  - conditional changes or changes with confirmation\n\t  - settings value change observation\n\n**If you have any suggestions and/or support to offer please file an issue in the repository & let me know, use `[Suggestion]` or `[FeatureRequest]` tags in issue titles**\n\n## 0.2.1+1\n* improved overall alignment of settings tiles\n* update cache provide code to make asynchronous calls to setter methods\n  - autoValidated parameter in text input settings is now deprecated and will be removed soon. User `autoValidateMode` parameter instead.\n* removed native platform dependency code as this library does not depend on native features. At least not directly.\n\n## 0.2.1\n* `SimpleSettingsTile` will take any widget as `child` instead of only `SettingsScreen`\n  - **Breaking**: parameter name changed from `screen` to `child` for consistency\n* Added `subtitle` property for most settings tiles to allow a describing how this setting may introduce change in behaviour of the app\n* Improved Settings title and subtitle text style for consistency in UI\n* `SliderSettings` now have 2 additional callbacks:\n  - onChangeStart - allows detecting drag start event\n  - onChangeEnd - allows detecting drag end event\n     - Using this allows changing the slider value only when user stops sliding\n* Updated Example code to reflect latest features \n\n## 0.2.0+1\n* improved plugin initialization, now supports async method call\n* resolved a bug where Radio Settings was not reflecting changes\n\n## 0.2.0\n* complete re-do of the whole library\n  * removed rx-dart dependency\n  * improved the working of the many existing settings widgets\n    * many of the choice based widgets now support any primitive value as input/output values instead of just strings\n    * added more customization choices per setting widget\n  * added a default cache provider which is based on `shared_preferences` library by flutter team\n* updated code documentation\n\n#### Breaking Change:\nYour existing use of some settings widgets might show error or not work as due to them being re-designed, like change in name/type of the parameters or the widget itself is renamed.\n\nThis was a major re-design/refactor of the library, so please re-test part of your code which uses this library.\n\n## 0.1.0+0.2\n* update in license file\n\n## 0.1.0+0.1\n* 0.1.0 release + update in documentation and sdk version constraints\n\n## 0.1.0\n* first release\n\n## 0.0.1\n* initial code release"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2019 Harshvardhan Joshi\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.\n"
  },
  {
    "path": "README.md",
    "content": "# flutter_settings_screens\n\n[![pub package](https://img.shields.io/pub/v/flutter_settings_screens.svg)](https://pub.dev/packages/flutter_settings_screens)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n\nThis is a simple flutter plugin for easily creating app settings screens.\nThe unique thing about this library is that it is not dependent upon any specific storage library used to store settings.\n\nInspired by the [shared_preferences_settings](https://pub.dev/packages/shared_preferences_settings) plugin.\n\n**Update: Now with Null-safety & Material3 support**\n\n## Features\n  - A collection of settings widgets to make a settings page in a few seconds and get going.\n    - **Normal**:\n      - SimpleSettingsTile\n      - Switch/Toggle setting\n      - Checkbox setting\n      - Drop down setting\n      - Radio selection Setting\n      - Slider setting\n      - Color choice panel\n      - Text Input Setting\n    - **Advanced**:\n      - SettingsScreen:\n        > A Flutter Widget/Page which can contain all settings widget.\n      - ExpandableSettingsTile\n          > A settings widget which can hold a set of widgets in a section which is collapsible\n      - SettingsContainer\n      > A Settings widget that helps any flutter widget fit into the settings page\n      - SettingsGroup\n      > A Container widget that creates a section with a title to separate settings inside this from other settings\n  - Settings saved via \"CacheProvider\" library of your choice\n    - default version uses SharedPreferences.\n  - Widgets with conditional visibility of some other settings.\n    - for example, A set of settings is only visible if a switch or a checkbox is enabled.\n\n\n## Examples\n![](https://github.com/GAM3RG33K/flutter_settings_screens/blob/master/media/example_1.gif?raw=true \"\")\n![](https://github.com/GAM3RG33K/flutter_settings_screens/blob/master/media/example_2.gif?raw=true \"\")\n![](https://github.com/GAM3RG33K/flutter_settings_screens/blob/master/media/example_3.gif?raw=true \"\")\n![](https://github.com/GAM3RG33K/flutter_settings_screens/blob/master/media/example_4.gif?raw=true \"\")\n![](https://github.com/GAM3RG33K/flutter_settings_screens/blob/master/media/example_5.gif?raw=true \"\")\n\n\n## Initializing the plugin\n\nInitialize the plugin as following:\n```dart\nawait Settings.init(cacheProvider: _customCacheProvider);\n```\n\n**Note**:\nThe plugin must be initialized before Navigating to the settings page.\n\nIt is recommended that `Settings.init()` should be called before `runApp()` is called in the main file. However, anywhere before showing the settings page is fine.\n\n\n### Cache Provider Interface\nCache Provider is an interface by which the plugin accesses the underlying caching storage.\n\nThis plugin includes an implementation of the `CacheProvider` using the `SharedPreferences` library by flutter. If `cacheProvider` parameter is not given explicitly then the default implementation will be used to store the settings.\n\nHowever, if you wish to use other means for storing the data,  you can implement one by yourself.\n\nAll you have to do is create a class as follows:\n```dart\nimport 'package:flutter_settings_screens/flutter_settings_screens.dart';\n\nclass CustomCacheProvider extends CacheProvider {\n    ///...\n    ///implement the methods as you want\n    ///...\n}\n```\n\nfor example,\n\n```dart\n/// A cache access provider class for shared preferences using shared_preferences library\nclass SharePreferenceCache extends CacheProvider {\n    //...\n}\n```\n\nOR\n\n```dart\n/// A cache access provider class for shared preferences using Hive library\nclass HiveCache extends CacheProvider {\n    //...\n}\n```\n\nOnce you implement the class, use an instance of this class to initialize the Settings class.\n\n\n## Accessing/Retrieving data\nYou can use static methods of `Settings` class to access any data from the storage.\n\nGet value:\n```dart\n Settings.getValue<T>(cacheKey, defaultValue);\n```\nSet value(no UI updates):\n```dart\n await Settings.setValue<T>(cacheKey, newValue);\n```\n\nSet value(with UI updates):\n```dart\n await Settings.setValue<T>(cacheKey, newValue, notify: true);\n```\n\nT represents any of the following:\n - String\n - bool\n - int\n - double\n - Object\n\nFor example if you want to access a String value from the storage:\nGet value:\n```dart\n Settings.getValue<String>(cacheKey, defaultValue);\n```\nSet value:\n```dart\n await Settings.setValue<String>(cacheKey, newValue, notify: true);\n```\n\n### Special-Note:\nSince, `Color` or `MaterialColor` is a Flutter object, we need to convert it to string version of the color before saving it to cache & convert string version to color while fetching it from the cache.\n\nFor that the plugin exposes `ConversionUtils` class with utility method to do that needed.\n\nFrom color to string:\n```dart\n String colorString = ConversionUtils.stringFromColor(Colors.blue);\n```\n\nFrom string to color:\n```dart\n Color color = ConversionUtils.colorFromString('#0000ff');\n```\n\n\n## Tile widgets\n\n#### SimpleSettingsTile\n\nSimpleSettingsTile is a simple settings tile that can open a new screen by tapping the tile.\n\nExample:\n```dart\nSimpleSettingsTile(\n  title: 'Advanced',\n  subtitle: 'More, advanced settings.'\n  screen: SettingsScreen(\n    title: 'Sub menu',\n    children: <Widget>[\n      CheckboxSettingsTile(\n        settingsKey: 'key-of-your-setting',\n        title: 'This is a simple Checkbox',\n      ),\n    ],\n  ),\n);\n```\n\n#### SettingsTileGroup\n\nSettingsGroup is a widget that contains multiple settings tiles and other widgets together as a group and shows a title/name of that group.\n\nAll the children widget will have small padding from the left and top to provide a sense that they in a separate group from others\n\nExample:\n```dart\nSettingsGroup(\n   title: 'Group title',\n   children: <Widget>[\n      CheckboxSettingsTile(\n        settingKey: 'key-day-light-savings',\n        title: 'Daylight Time Saving',\n        enabledLabel: 'Enabled',\n        disabledLabel: 'Disabled',\n        leading: Icon(Icons.timelapse),\n      ),\n      SwitchSettingsTile(\n        settingKey: 'key-dark-mode',\n        title: 'Dark Mode',\n        enabledLabel: 'Enabled',\n        disabledLabel: 'Disabled',\n        leading: Icon(Icons.palette),\n      ),\n     ],\n );\n```\n\n\n#### ExpandableSettingsTile\nExpandableSettingsTile is a wrapper widget that shows the given children when expanded by clicking on the tile.\n\nExample:\n```dart\n ExpandableSettingsTile(\n   title: 'Quick setting dialog2',\n   subtitle: 'Expandable Settings',\n   children: <Widget>[\n     CheckboxSettingsTile(\n       settingKey: 'key-day-light-savings',\n       title: 'Daylight Time Saving',\n       enabledLabel: 'Enabled',\n       disabledLabel: 'Disabled',\n       leading: Icon(Icons.timelapse),\n     ),\n     SwitchSettingsTile(\n       settingKey: 'key-dark-mode',\n       title: 'Dark Mode',\n       enabledLabel: 'Enabled',\n       disabledLabel: 'Disabled',\n       leading: Icon(Icons.palette),\n     ),\n   ],\n );\n```\n\n#### CheckboxSettingsTile\n\nCheckboxSettingsTile is a widget that has a Checkbox with given title, subtitle and default value/status of the Checkbox\n\nThis widget supports an additional list of widgets to display when the Checkbox is checked. This optional list of widgets is accessed through `childrenIfEnabled` property of this widget.\n\nThis widget works similar to `SwitchSettingsTile`.\n\nExample:\n```dart\n CheckboxSettingsTile(\n  leading: Icon(Icons.developer_mode),\n  settingKey: 'key-check-box-dev-mode',\n  title: 'Developer Settings',\n  onChange: (value) {\n    debugPrint('key-check-box-dev-mode: $value');\n  },\n  childrenIfEnabled: <Widget>[\n    CheckboxSettingsTile(\n      leading: Icon(Icons.adb),\n      settingKey: 'key-is-developer',\n      title: 'Developer Mode',\n      onChange: (value) {\n        debugPrint('key-is-developer: $value');\n      },\n    ),\n    SwitchSettingsTile(\n      leading: Icon(Icons.usb),\n      settingKey: 'key-is-usb-debugging',\n      title: 'USB Debugging',\n      onChange: (value) {\n        debugPrint('key-is-usb-debugging: $value');\n      },\n    ),\n  ],\n );\n```\n\n#### SwitchSettingsTile\nSwitchSettingsTile is a widget that has a Switch with given title, subtitle and default value/status of the switch\n\nThis widget supports an additional list of widgets to display when the switch is enabled. This optional list of widgets is accessed through `childrenIfEnabled` property of this widget.\n\nThis widget works similar to `CheckboxSettingsTile`.\n\nExample:\n```dart\n SwitchSettingsTile(\n  leading: Icon(Icons.developer_mode),\n  settingKey: 'key-switch-dev-mode',\n  title: 'Developer Settings',\n  onChange: (value) {\n    debugPrint('key-switch-dev-mod: $value');\n  },\n  childrenIfEnabled: <Widget>[\n    CheckboxSettingsTile(\n      leading: Icon(Icons.adb),\n      settingKey: 'key-is-developer',\n      title: 'Developer Mode',\n      onChange: (value) {\n        debugPrint('key-is-developer: $value');\n      },\n    ),\n    SwitchSettingsTile(\n      leading: Icon(Icons.usb),\n      settingKey: 'key-is-usb-debugging',\n      title: 'USB Debugging',\n      onChange: (value) {\n        debugPrint('key-is-usb-debugging: $value');\n      },\n    ),\n    SimpleSettingsTile(\n      title: 'Root Settings',\n      subtitle: 'These settings is not accessible',\n      enabled: false,\n    )\n  ],\n );\n ```\n\n#### RadioSettingsTile\nRadioSettingsTile is a widget that has a list of Radio widgets with given title, subtitle and default/group value which determines which Radio will be selected initially.\n\nThis widget supports Any type of values which should be put in the preference.\n\nHowever, since any type of value is supported, the input for this widget is a Map to the required values with their string representation.\n\nFor example, if the required value type is a boolean then the values map can be as following:\n ```dart\n <bool, String> {\n    true: 'Enabled',\n    false: 'Disabled'\n }\n ```\n\nSo, if the `Enabled` value radio is selected then the value `true` will be stored in the preference\n\nComplete Example:\n```dart\nRadioSettingsTile<int>(\n  title: 'Preferred Sync Period',\n  settingKey: 'key-radio-sync-period',\n  values: <int, String>{\n    0: 'Never',\n    1: 'Daily',\n    7: 'Weekly',\n    15: 'Fortnight',\n    30: 'Monthly',\n  },\n  selected: 0,\n  onChange: (value) {\n    debugPrint('key-radio-sync-period: $value days');\n  },\n)\n```\n\n#### DropDownSettingTile\nDropDownSettingsTile is a widget that has a list of DropdownMenuItems with given title, subtitle and default/group value which determines which value will be set to selected initially.\n\nThis widget supports Any type of values which should be put in the preference.\n\nHowever, since any type of value is supported, the input for this widget is a Map to the required values with their string representation.\n\nFor example, if the required value type is a boolean then the values map can\nbe as following:\n```dart\n <bool, String> {\n    true: 'Enabled',\n    false: 'Disabled'\n }\n ```\n\nSo, if the `Enabled` value is selected then the value `true` will be stored in the preference\n\nComplete Example:\n```dart\nDropDownSettingsTile<int>(\n  title: 'E-Mail View',\n  settingKey: 'key-dropdown-email-view',\n  values: <int, String>{\n    2: 'Simple',\n    3: 'Adjusted',\n    4: 'Normal',\n    5: 'Compact',\n    6: 'Squizzed',\n  },\n  selected: 2,\n  onChange: (value) {\n    debugPrint('key-dropdown-email-view: $value');\n  },\n);\n```\n\n#### SliderSettingsTile\nSliderSettingsTile is a widget that has a slider given title, subtitle and default value which determines what the slider's position will be set initially.\n\nThis widget supports double and integer types of values which should be put in the preference.\n\nExample:\n```dart\nSliderSettingsTile(\n title: 'Volume',\n settingKey: 'key-slider-volume',\n defaultValue: 20,\n min: 0,\n max: 100,\n step: 1,\n leading: Icon(Icons.volume_up),\n onChange: (value) {\n   debugPrint('key-slider-volume: $value');\n },\n);\n```\n\n\n## Modal widgets\n\n#### RadioModalSettingsTile\nRadioModalSettingsTile widget is the dialog version of the `RadioSettingsTile` widget.\n\nThe use of this widget is similar to the RadioSettingsTile, only the displayed widget will be in a different position.\n\ni.e instead of inside the settings screen, it will be shown in a dialog above the settings screen.\n\nExample:\n```dart\nRadioModalSettingsTile<int>(\n  title: 'Preferred Sync Period',\n  settingKey: 'key-radio-sync-period',\n  values: <int, String>{\n    0: 'Never',\n    1: 'Daily',\n    7: 'Weekly',\n    15: 'Fortnight',\n    30: 'Monthly',\n  },\n  selected: 0,\n  onChange: (value) {\n    debugPrint('key-radio-sync-period: $value days');\n  },\n);\n```\n\n#### SliderModalSettingsTile\nSliderModalSettingsTile widget is the dialog version of the SliderSettingsTile widget.\n\nThe use of this widget is similar to the SliderSettingsTile, only the displayed widget will be in a different position.\n\ni.e instead of inside the settings screen, it will be shown in a dialog above the settings screen.\n\nExample:\n```dart\nSliderSettingsTile(\n title: 'Volume',\n settingKey: 'key-slider-volume',\n defaultValue: 20,\n min: 0,\n max: 100,\n step: 1,\n leading: Icon(Icons.volume_up),\n onChange: (value) {\n   debugPrint('key-slider-volume: $value');\n },\n);\n```\n\n\n#### TextInputSettingsTile\nA Setting widget which allows user a text input in a TextFormField.\n\nExample:\n```dart\nTextInputSettingsTile(\n  title: 'User Name',\n  settingKey: 'key-user-name',\n  initialValue: 'admin',\n  validator: (String username) {\n    if (username != null && username.length > 3) {\n      return null;\n    }\n    return \"User Name can't be smaller than 4 letters\";\n  },\n  borderColor: Colors.blueAccent,\n  errorColor: Colors.deepOrangeAccent,\n);\n```\n\n OR\n\n``` dart\nTextInputSettingsTile(\n  title: 'password',\n  settingKey: 'key-user-password',\n  obscureText: true,\n  validator: (String password) {\n    if (password != null && password.length > 6) {\n      return null;\n    }\n    return \"Password can't be smaller than 7 letters\";\n  },\n  borderColor: Colors.blueAccent,\n  errorColor: Colors.deepOrangeAccent,\n);\n```\n\n#### ColorPickerSettingsTile\nColorPickerSettingsTile is a widget which allows user to select a color from a set of Material color choices.\n\nSince, `Color` is an in-memory object type, the serialized version of the value of this widget will be a Hex value String of the selected color.\n\nFor example, If selected color is `red` then the stored value will be \"#ffff0000\", but when retrieved, the value will be an instance of `Color` with properties of red color.\n\nThis conversion string <-> color, makes this easy to check/debug the values from the storage/preference manually.\n\nThe color panel shown in the widget is provided by the `flutter_material_color_picker` library.\n\nExample:\n```dart\n ColorPickerSettingsTile(\n   settingKey: 'key-color-picker',\n   title: 'Accent Color',\n   defaultValue: Colors.blue,\n   onChange: (value) {\n     debugPrint('key-color-picker: $value');\n   },\n );\n```\n\n## Utility widgets\n\n#### SettingsScreen\nA simple Screen widget that may contain settings tiles or other widgets.\nThe following example shows how you can create an empty settings screen with a title:\n\n```dart\nSettingsScreen(\n    title: \"Application Settings\",\n    children: [],\n);\n```\n\nInside the children parameter, you can define settings tiles and other widgets. In this example we create a screen with a simple CheckboxSettingsTile in it:\n\n```dart\nSettingsScreen(\n    title: \"Application Settings\",\n    children:\n        CheckboxSettingsTile(\n            settingKey: 'key-of-your-setting',\n            title: 'This is a simple Checkbox',\n        ),\n    ,\n);\n```\n\n#### SettingsContainer\nA widget that helps its child or children to fin in the settings screen. It is helpful if you want to place other widgets than settings tiles in the settings screen body.\nThe following example shows how you can create a container with one Text widget:\n```dart\nSettingsContainer(\n    child: Text('Hello world'),\n);\n```\nIn this example, we create a container with multiple Text widgets:\n```dart\nSettingsContainer(\n    children:\n        Text('First line'),\n        Text('Second line'),\n    ],\n);\n```\n\n## Alternate widgets\n\n#### SimpleRadioSettingsTile\nSimpleRadioSettingsTile is a simpler version of the RadioSettingsTile.\nInstead of a Value-String map, this widget just takes a list of String values.\n\nIn this widget, the displayed value and the stored value will be the same.\n\nExample:\n```dart\nSimpleRadioSettingsTile(\n  title: 'Sync Settings',\n  settingKey: 'key-radio-sync-settings',\n  values: <String>[\n    'Never',\n    'Daily',\n    'Weekly',\n    'Fortnight',\n    'Monthly',\n  ],\n  selected: 'Daily',\n  onChange: (value) {\n    debugPrint('key-radio-sync-settings: $value');\n  },\n);\n```\n\n#### SimpleDropDownSettingsTile\nSimpleDropDownSettingsTile is a simpler version of the DropDownSettingsTile.\nInstead of a Value-String map, this widget just takes a list of String values.\n\nIn this widget, the displayed value and the stored value will be the same.\n\nExample:\n```dart\nSimpleDropDownSettingsTile(\n  title: 'Beauty Filter',\n  settingKey: 'key-dropdown-beauty-filter',\n  values: <String>[\n    'Simple',\n    'Normal',\n    'Little Special',\n    'Special',\n    'Extra Special',\n    'Bizarre',\n    'Horrific',\n  ],\n  selected: 'Special',\n  onChange: (value) {\n    debugPrint('key-dropdown-beauty-filter: $value');\n },\n);\n```\n\n## Contribution/Support\n- File an issue on the repository, if something is not working as expected.\n   - Please follow the issue template used in flutter-sdk's repository, may be we'll integrate that here as well.\n- File an issue in the repository, If you have any suggestions and/or feature requests, use `[Suggestion]` or `[FeatureRequest]` tags in issue titles.\n- To support you just have to help out fellow developers on of the filed issues in this repository.\n- To contribute, just follow the standard open source contributions instructions, maybe we can follow the ones used in the flutter sdk. We'll see how it goes.\n\n\n**All help, issues, support and contributions are most welcome.**\n\n_If any one is interested in helping me maintain this library then please reach to me via comment on this [issue](https://github.com/GAM3RG33K/flutter_settings_screens/issues/86)._\n"
  },
  {
    "path": "analysis_options.yaml",
    "content": "# This file configures the analyzer, which statically analyzes Dart code to\n# check for errors, warnings, and lints.\n#\n# The issues identified by the analyzer are surfaced in the UI of Dart-enabled\n# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be\n# invoked from the command line by running `flutter analyze`.\n\n# The following line activates a set of recommended lints for Flutter apps,\n# packages, and plugins designed to encourage good coding practices.\ninclude: package:flutter_lints/flutter.yaml\n\nlinter:\n  # The lint rules applied to this project can be customized in the\n  # section below to disable rules from the `package:flutter_lints/flutter.yaml`\n  # included above or to enable additional rules. A list of all available lints\n  # and their documentation is published at https://dart.dev/lints.\n  #\n  # Instead of disabling a lint rule for the entire project in the\n  # section below, it can also be suppressed for a single line of code\n  # or a specific dart file by using the `// ignore: name_of_lint` and\n  # `// ignore_for_file: name_of_lint` syntax on the line or in the file\n  # producing the lint.\n  rules:\n    # avoid_print: false  # Uncomment to disable the `avoid_print` rule\n    # prefer_single_quotes: true  # Uncomment to enable the `prefer_single_quotes` rule\n\n# Additional information about this file can be found at\n# https://dart.dev/guides/language/analysis-options\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.fvm/\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.dart_tool/\n.flutter-plugins\n.packages\n.pub-cache/\n.pub/\n/build/\npubspec.lock\n\n# Web related\nlib/generated_plugin_registrant.dart\n\n# Exceptions to above rules.\n!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages\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: 2c7af1e24e45a79f4eb73d67d98fcecea8bf6146\n  channel: master\n\nproject_type: app\n"
  },
  {
    "path": "example/README.md",
    "content": "# flutter_settings_screens_example\n\nDemonstrates how to use the flutter_settings_screens 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**/*.keystore\n**/*.jks\n"
  },
  {
    "path": "example/android/app/build.gradle",
    "content": "\nplugins {\n    id \"com.android.application\"\n    id \"dev.flutter.flutter-gradle-plugin\"\n}\n\ndef 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 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\nandroid {\n    namespace \"com.happyworks.flutter_settings_screens_example\"\n    compileSdkVersion flutter.compileSdkVersion\n\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n\n    defaultConfig {\n        applicationId \"com.happyworks.flutter_settings_screens_example\"\n        minSdkVersion flutter.minSdkVersion\n        targetSdkVersion flutter.targetSdkVersion\n        versionCode flutterVersionCode.toInteger()\n        versionName flutterVersionName\n    }\n\n    buildTypes {\n        release {\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}\n"
  },
  {
    "path": "example/android/app/src/debug/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.happyworks.flutter_settings_screens_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=\"com.happyworks.flutter_settings_screens_example\">\n\n    <application\n        android:name=\"${applicationName}\"\n        android:label=\"example\"\n        android:icon=\"@mipmap/ic_launcher\">\n        <activity\n            android:name=\".MainActivity\"\n            android:exported=\"true\"\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            <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/java/com/happyworks/flutter_settings_screens_example/MainActivity.java",
    "content": "package com.happyworks.flutter_settings_screens_example;\n\nimport io.flutter.embedding.android.FlutterActivity;\n\npublic class MainActivity extends FlutterActivity {\n}\n"
  },
  {
    "path": "example/android/app/src/main/res/drawable/launch_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!-- 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/drawable-v21/launch_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!-- 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:colorBackground\" />\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 when the OS's Dark Mode setting is off -->\n    <style name=\"LaunchTheme\" parent=\"@android:style/Theme.Light.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.Light.NoTitleBar\">\n        <item name=\"android:windowBackground\">?android:colorBackground</item>\n    </style>\n</resources>\n"
  },
  {
    "path": "example/android/app/src/main/res/values-night/styles.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->\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:colorBackground</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=\"com.happyworks.flutter_settings_screens_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": "allprojects {\n    repositories {\n        google()\n        mavenCentral()\n    }\n}\n\nrootProject.layout.buildDirectory = '../build'\nsubprojects {\n    project.layout.buildDirectory = rootProject.layout.buildDirectory.dir(project.name)\n}\nsubprojects {\n    project.evaluationDependsOn(':app')\n}\n\ntasks.register(\"clean\", Delete) {\n    delete rootProject.layout.buildDirectory\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-8.6-all.zip\n"
  },
  {
    "path": "example/android/gradle.properties",
    "content": "org.gradle.jvmargs=-Xmx1536M\nandroid.useAndroidX=true\nandroid.enableJetifier=true\n"
  },
  {
    "path": "example/android/settings.gradle",
    "content": "pluginManagement {\n    def flutterSdkPath = {\n        def properties = new Properties()\n        file(\"local.properties\").withInputStream { properties.load(it) }\n        def flutterSdkPath = properties.getProperty(\"flutter.sdk\")\n        assert flutterSdkPath != null, \"flutter.sdk not set in local.properties\"\n        return flutterSdkPath\n    }()\n\n    includeBuild(\"$flutterSdkPath/packages/flutter_tools/gradle\")\n\n    repositories {\n        google()\n        mavenCentral()\n        gradlePluginPortal()\n    }\n}\n\nplugins {\n    id \"dev.flutter.flutter-plugin-loader\" version \"1.0.0\"\n    id \"com.android.application\" version '8.4.0' apply false\n}\n\ninclude ':app'\n"
  },
  {
    "path": "example/ios/.gitignore",
    "content": "**/dgph\n*.mode1v3\n*.mode2v3\n*.moved-aside\n*.pbxuser\n*.perspectivev3\n**/*sync/\n.sconsign.dblite\n.tags*\n**/.vagrant/\n**/DerivedData/\nIcon?\n**/Pods/\n**/.symlinks/\nprofile\nxcuserdata\n**/.generated/\nFlutter/App.framework\nFlutter/Flutter.framework\nFlutter/Flutter.podspec\nFlutter/Generated.xcconfig\nFlutter/ephemeral/\nFlutter/app.flx\nFlutter/app.zip\nFlutter/flutter_assets/\nFlutter/flutter_export_environment.sh\nServiceDefinitions.json\nRunner/GeneratedPluginRegistrant.*\n\n# Exceptions to above rules.\n!default.mode1v3\n!default.mode2v3\n!default.pbxuser\n!default.perspectivev3\n"
  },
  {
    "path": "example/ios/Flutter/AppFrameworkInfo.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n  <key>CFBundleDevelopmentRegion</key>\n  <string>en</string>\n  <key>CFBundleExecutable</key>\n  <string>App</string>\n  <key>CFBundleIdentifier</key>\n  <string>io.flutter.flutter.app</string>\n  <key>CFBundleInfoDictionaryVersion</key>\n  <string>6.0</string>\n  <key>CFBundleName</key>\n  <string>App</string>\n  <key>CFBundlePackageType</key>\n  <string>FMWK</string>\n  <key>CFBundleShortVersionString</key>\n  <string>1.0</string>\n  <key>CFBundleSignature</key>\n  <string>????</string>\n  <key>CFBundleVersion</key>\n  <string>1.0</string>\n  <key>MinimumOSVersion</key>\n  <string>12.0</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "example/ios/Flutter/Debug.xcconfig",
    "content": "#include? \"Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig\"\n#include \"Generated.xcconfig\"\n"
  },
  {
    "path": "example/ios/Flutter/Release.xcconfig",
    "content": "#include? \"Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig\"\n#include \"Generated.xcconfig\"\n"
  },
  {
    "path": "example/ios/Podfile",
    "content": "# Uncomment this line to define a global platform for your project\n# platform :ios, '12.0'\n\n# CocoaPods analytics sends network stats synchronously affecting flutter build latency.\nENV['COCOAPODS_DISABLE_STATS'] = 'true'\n\nproject 'Runner', {\n  'Debug' => :debug,\n  'Profile' => :release,\n  'Release' => :release,\n}\n\ndef flutter_root\n  generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)\n  unless File.exist?(generated_xcode_build_settings_path)\n    raise \"#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first\"\n  end\n\n  File.foreach(generated_xcode_build_settings_path) do |line|\n    matches = line.match(/FLUTTER_ROOT\\=(.*)/)\n    return matches[1].strip if matches\n  end\n  raise \"FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get\"\nend\n\nrequire File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)\n\nflutter_ios_podfile_setup\n\ntarget 'Runner' do\n  use_frameworks!\n  use_modular_headers!\n\n  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))\nend\n\npost_install do |installer|\n  installer.pods_project.targets.each do |target|\n    flutter_additional_ios_build_settings(target)\n  end\nend\n"
  },
  {
    "path": "example/ios/Runner/AppDelegate.swift",
    "content": "import UIKit\nimport Flutter\n\n@UIApplicationMain\n@objc class AppDelegate: FlutterAppDelegate {\n  override func application(\n    _ application: UIApplication,\n    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?\n  ) -> Bool {\n    GeneratedPluginRegistrant.register(with: self)\n    return super.application(application, didFinishLaunchingWithOptions: launchOptions)\n  }\n}\n"
  },
  {
    "path": "example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\": [\n    {\n      \"size\": \"20x20\",\n      \"idiom\": \"iphone\",\n      \"filename\": \"Icon-App-20x20@2x.png\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"20x20\",\n      \"idiom\": \"iphone\",\n      \"filename\": \"Icon-App-20x20@3x.png\",\n      \"scale\": \"3x\"\n    },\n    {\n      \"size\": \"29x29\",\n      \"idiom\": \"iphone\",\n      \"filename\": \"Icon-App-29x29@1x.png\",\n      \"scale\": \"1x\"\n    },\n    {\n      \"size\": \"29x29\",\n      \"idiom\": \"iphone\",\n      \"filename\": \"Icon-App-29x29@2x.png\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"29x29\",\n      \"idiom\": \"iphone\",\n      \"filename\": \"Icon-App-29x29@3x.png\",\n      \"scale\": \"3x\"\n    },\n    {\n      \"size\": \"40x40\",\n      \"idiom\": \"iphone\",\n      \"filename\": \"Icon-App-40x40@2x.png\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"40x40\",\n      \"idiom\": \"iphone\",\n      \"filename\": \"Icon-App-40x40@3x.png\",\n      \"scale\": \"3x\"\n    },\n    {\n      \"size\": \"60x60\",\n      \"idiom\": \"iphone\",\n      \"filename\": \"Icon-App-60x60@2x.png\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"60x60\",\n      \"idiom\": \"iphone\",\n      \"filename\": \"Icon-App-60x60@3x.png\",\n      \"scale\": \"3x\"\n    },\n    {\n      \"size\": \"20x20\",\n      \"idiom\": \"ipad\",\n      \"filename\": \"Icon-App-20x20@1x.png\",\n      \"scale\": \"1x\"\n    },\n    {\n      \"size\": \"20x20\",\n      \"idiom\": \"ipad\",\n      \"filename\": \"Icon-App-20x20@2x.png\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"29x29\",\n      \"idiom\": \"ipad\",\n      \"filename\": \"Icon-App-29x29@1x.png\",\n      \"scale\": \"1x\"\n    },\n    {\n      \"size\": \"29x29\",\n      \"idiom\": \"ipad\",\n      \"filename\": \"Icon-App-29x29@2x.png\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"40x40\",\n      \"idiom\": \"ipad\",\n      \"filename\": \"Icon-App-40x40@1x.png\",\n      \"scale\": \"1x\"\n    },\n    {\n      \"size\": \"40x40\",\n      \"idiom\": \"ipad\",\n      \"filename\": \"Icon-App-40x40@2x.png\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"76x76\",\n      \"idiom\": \"ipad\",\n      \"filename\": \"Icon-App-76x76@1x.png\",\n      \"scale\": \"1x\"\n    },\n    {\n      \"size\": \"76x76\",\n      \"idiom\": \"ipad\",\n      \"filename\": \"Icon-App-76x76@2x.png\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"83.5x83.5\",\n      \"idiom\": \"ipad\",\n      \"filename\": \"Icon-App-83.5x83.5@2x.png\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"1024x1024\",\n      \"idiom\": \"ios-marketing\",\n      \"filename\": \"Icon-App-1024x1024@1x.png\",\n      \"scale\": \"1x\"\n    }\n  ],\n  \"info\": {\n    \"version\": 1,\n    \"author\": \"xcode\"\n  }\n}\n"
  },
  {
    "path": "example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json",
    "content": "{\n  \"images\": [\n    {\n      \"idiom\": \"universal\",\n      \"filename\": \"LaunchImage.png\",\n      \"scale\": \"1x\"\n    },\n    {\n      \"idiom\": \"universal\",\n      \"filename\": \"LaunchImage@2x.png\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"idiom\": \"universal\",\n      \"filename\": \"LaunchImage@3x.png\",\n      \"scale\": \"3x\"\n    }\n  ],\n  \"info\": {\n    \"version\": 1,\n    \"author\": \"xcode\"\n  }\n}\n"
  },
  {
    "path": "example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md",
    "content": "# Launch Screen Assets\n\nYou can customize the launch screen with your own desired assets by replacing the image files in this directory.\n\nYou can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images."
  },
  {
    "path": "example/ios/Runner/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"12121\" systemVersion=\"16G29\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"12089\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <layoutGuides>\n                        <viewControllerLayoutGuide type=\"top\" id=\"Ydg-fD-yQy\"/>\n                        <viewControllerLayoutGuide type=\"bottom\" id=\"xbc-2k-c8Z\"/>\n                    </layoutGuides>\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <imageView opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" image=\"LaunchImage\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"YRO-k0-Ey4\">\n                            </imageView>\n                        </subviews>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <constraints>\n                            <constraint firstItem=\"YRO-k0-Ey4\" firstAttribute=\"centerX\" secondItem=\"Ze5-6b-2t3\" secondAttribute=\"centerX\" id=\"1a2-6s-vTC\"/>\n                            <constraint firstItem=\"YRO-k0-Ey4\" firstAttribute=\"centerY\" secondItem=\"Ze5-6b-2t3\" secondAttribute=\"centerY\" id=\"4X2-HB-R7a\"/>\n                        </constraints>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n    <resources>\n        <image name=\"LaunchImage\" width=\"168\" height=\"185\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "example/ios/Runner/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"10117\" systemVersion=\"15F34\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" initialViewController=\"BYZ-38-t0r\">\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"10085\"/>\n    </dependencies>\n    <scenes>\n        <!--Flutter View Controller-->\n        <scene sceneID=\"tne-QT-ifu\">\n            <objects>\n                <viewController id=\"BYZ-38-t0r\" customClass=\"FlutterViewController\" sceneMemberID=\"viewController\">\n                    <layoutGuides>\n                        <viewControllerLayoutGuide type=\"top\" id=\"y3c-jy-aDJ\"/>\n                        <viewControllerLayoutGuide type=\"bottom\" id=\"wfy-db-euE\"/>\n                    </layoutGuides>\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"8bC-Xf-vdC\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"600\" height=\"600\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"calibratedWhite\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"dkx-z0-nzr\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "example/ios/Runner/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleDisplayName</key>\n\t<string>Example</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>flutter_settings_screens_example</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>$(FLUTTER_BUILD_NAME)</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>$(FLUTTER_BUILD_NUMBER)</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UIViewControllerBasedStatusBarAppearance</key>\n\t<false/>\n\t<key>CADisableMinimumFrameDurationOnPhone</key>\n\t<true/>\n\t<key>UIApplicationSupportsIndirectInputEvents</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "example/ios/Runner/Runner-Bridging-Header.h",
    "content": "#import \"GeneratedPluginRegistrant.h\"\n"
  },
  {
    "path": "example/ios/Runner.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 54;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };\n\t\t2D304D1C1AD25E7DB8EB1CA0 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 56463CB180FDED103A6CB9C3 /* Pods_Runner.framework */; };\n\t\t3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };\n\t\t74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };\n\t\t97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };\n\t\t97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };\n\t\t97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXCopyFilesBuildPhase section */\n\t\t9705A1C41CF9048500538489 /* Embed Frameworks */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = \"\";\n\t\t\tdstSubfolderSpec = 10;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tname = \"Embed Frameworks\";\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXCopyFilesBuildPhase section */\n\n/* Begin PBXFileReference section */\n\t\t1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = \"<group>\"; };\n\t\t1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = \"<group>\"; };\n\t\t17AD69071B14EF34D761EA0E /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-Runner.release.xcconfig\"; path = \"Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = \"<group>\"; };\n\t\t56463CB180FDED103A6CB9C3 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"Runner-Bridging-Header.h\"; sourceTree = \"<group>\"; };\n\t\t74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\t7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = \"<group>\"; };\n\t\t9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = \"<group>\"; };\n\t\t9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = \"<group>\"; };\n\t\t97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\t97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\t97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tB7FD848EF692798DFEB371FA /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-Runner.profile.xcconfig\"; path = \"Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig\"; sourceTree = \"<group>\"; };\n\t\tD4AD61949C3A50BB5618FC8E /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-Runner.debug.xcconfig\"; path = \"Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig\"; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t97C146EB1CF9000F007C117D /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t2D304D1C1AD25E7DB8EB1CA0 /* Pods_Runner.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t9740EEB11CF90186004384FC /* Flutter */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,\n\t\t\t\t9740EEB21CF90195004384FC /* Debug.xcconfig */,\n\t\t\t\t7AFA3C8E1D35360C0083082E /* Release.xcconfig */,\n\t\t\t\t9740EEB31CF90195004384FC /* Generated.xcconfig */,\n\t\t\t);\n\t\t\tname = Flutter;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t974384AC923C661FE6D16947 /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t56463CB180FDED103A6CB9C3 /* Pods_Runner.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t97C146E51CF9000F007C117D = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9740EEB11CF90186004384FC /* Flutter */,\n\t\t\t\t97C146F01CF9000F007C117D /* Runner */,\n\t\t\t\t97C146EF1CF9000F007C117D /* Products */,\n\t\t\t\tC03ACAA41C034593E01687FB /* Pods */,\n\t\t\t\t974384AC923C661FE6D16947 /* Frameworks */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t97C146EF1CF9000F007C117D /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t97C146EE1CF9000F007C117D /* Runner.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t97C146F01CF9000F007C117D /* Runner */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t97C146FA1CF9000F007C117D /* Main.storyboard */,\n\t\t\t\t97C146FD1CF9000F007C117D /* Assets.xcassets */,\n\t\t\t\t97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,\n\t\t\t\t97C147021CF9000F007C117D /* Info.plist */,\n\t\t\t\t1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,\n\t\t\t\t1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,\n\t\t\t\t74858FAE1ED2DC5600515810 /* AppDelegate.swift */,\n\t\t\t\t74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,\n\t\t\t);\n\t\t\tpath = Runner;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC03ACAA41C034593E01687FB /* Pods */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tD4AD61949C3A50BB5618FC8E /* Pods-Runner.debug.xcconfig */,\n\t\t\t\t17AD69071B14EF34D761EA0E /* Pods-Runner.release.xcconfig */,\n\t\t\t\tB7FD848EF692798DFEB371FA /* Pods-Runner.profile.xcconfig */,\n\t\t\t);\n\t\t\tname = Pods;\n\t\t\tpath = Pods;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t97C146ED1CF9000F007C117D /* Runner */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget \"Runner\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t17F39D70C0DB2A58A43E2364 /* [CP] Check Pods Manifest.lock */,\n\t\t\t\t9740EEB61CF901F6004384FC /* Run Script */,\n\t\t\t\t97C146EA1CF9000F007C117D /* Sources */,\n\t\t\t\t97C146EB1CF9000F007C117D /* Frameworks */,\n\t\t\t\t97C146EC1CF9000F007C117D /* Resources */,\n\t\t\t\t9705A1C41CF9048500538489 /* Embed Frameworks */,\n\t\t\t\t3B06AD1E1E4923F5004D2608 /* Thin Binary */,\n\t\t\t\tE0B88306847A324AD9DFA0C9 /* [CP] Embed Pods Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = Runner;\n\t\t\tproductName = Runner;\n\t\t\tproductReference = 97C146EE1CF9000F007C117D /* Runner.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t97C146E61CF9000F007C117D /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastUpgradeCheck = 1510;\n\t\t\t\tORGANIZATIONNAME = \"\";\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t97C146ED1CF9000F007C117D = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 7.3.1;\n\t\t\t\t\t\tLastSwiftMigration = 1100;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject \"Runner\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 97C146E51CF9000F007C117D;\n\t\t\tproductRefGroup = 97C146EF1CF9000F007C117D /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t97C146ED1CF9000F007C117D /* Runner */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t97C146EC1CF9000F007C117D /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,\n\t\t\t\t3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,\n\t\t\t\t97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,\n\t\t\t\t97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\t17F39D70C0DB2A58A43E2364 /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\t3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\talwaysOutOfDate = 1;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}\",\n\t\t\t);\n\t\t\tname = \"Thin Binary\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"/bin/sh \\\"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\\\" embed_and_thin\";\n\t\t};\n\t\t9740EEB61CF901F6004384FC /* Run Script */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\talwaysOutOfDate = 1;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Run Script\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"/bin/sh \\\"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\\\" build\";\n\t\t};\n\t\tE0B88306847A324AD9DFA0C9 /* [CP] Embed Pods Frameworks */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist\",\n\t\t\t);\n\t\t\tname = \"[CP] Embed Pods Frameworks\";\n\t\t\toutputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"\\\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t97C146EA1CF9000F007C117D /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,\n\t\t\t\t1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXVariantGroup section */\n\t\t97C146FA1CF9000F007C117D /* Main.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t97C146FB1CF9000F007C117D /* Base */,\n\t\t\t);\n\t\t\tname = Main.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t97C147001CF9000F007C117D /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t249021D3217E4FDB00AE95B9 /* Profile */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSUPPORTED_PLATFORMS = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Profile;\n\t\t};\n\t\t249021D4217E4FDB00AE95B9 /* Profile */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCURRENT_PROJECT_VERSION = \"$(FLUTTER_BUILD_NUMBER)\";\n\t\t\t\tENABLE_BITCODE = NO;\n\t\t\t\tINFOPLIST_FILE = Runner/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.example.example;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"Runner/Runner-Bridging-Header.h\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t};\n\t\t\tname = Profile;\n\t\t};\n\t\t97C147031CF9000F007C117D /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t97C147041CF9000F007C117D /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSUPPORTED_PLATFORMS = iphoneos;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t97C147061CF9000F007C117D /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCURRENT_PROJECT_VERSION = \"$(FLUTTER_BUILD_NUMBER)\";\n\t\t\t\tENABLE_BITCODE = NO;\n\t\t\t\tINFOPLIST_FILE = Runner/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.example.example;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"Runner/Runner-Bridging-Header.h\";\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t97C147071CF9000F007C117D /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCURRENT_PROJECT_VERSION = \"$(FLUTTER_BUILD_NUMBER)\";\n\t\t\t\tENABLE_BITCODE = NO;\n\t\t\t\tINFOPLIST_FILE = Runner/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.example.example;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"Runner/Runner-Bridging-Header.h\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t97C146E91CF9000F007C117D /* Build configuration list for PBXProject \"Runner\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t97C147031CF9000F007C117D /* Debug */,\n\t\t\t\t97C147041CF9000F007C117D /* Release */,\n\t\t\t\t249021D3217E4FDB00AE95B9 /* Profile */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget \"Runner\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t97C147061CF9000F007C117D /* Debug */,\n\t\t\t\t97C147071CF9000F007C117D /* Release */,\n\t\t\t\t249021D4217E4FDB00AE95B9 /* Profile */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 97C146E61CF9000F007C117D /* Project object */;\n}\n"
  },
  {
    "path": "example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEDidComputeMac32BitWarning</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>PreviewsEnabled</key>\n\t<false/>\n</dict>\n</plist>\n"
  },
  {
    "path": "example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1510\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"97C146ED1CF9000F007C117D\"\n               BuildableName = \"Runner.app\"\n               BlueprintName = \"Runner\"\n               ReferencedContainer = \"container:Runner.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"97C146ED1CF9000F007C117D\"\n            BuildableName = \"Runner.app\"\n            BlueprintName = \"Runner\"\n            ReferencedContainer = \"container:Runner.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"97C146ED1CF9000F007C117D\"\n            BuildableName = \"Runner.app\"\n            BlueprintName = \"Runner\"\n            ReferencedContainer = \"container:Runner.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Profile\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"97C146ED1CF9000F007C117D\"\n            BuildableName = \"Runner.app\"\n            BlueprintName = \"Runner\"\n            ReferencedContainer = \"container:Runner.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "example/ios/Runner.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"group:Runner.xcodeproj\">\n   </FileRef>\n   <FileRef\n      location = \"group:Pods/Pods.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEDidComputeMac32BitWarning</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>PreviewsEnabled</key>\n\t<false/>\n</dict>\n</plist>\n"
  },
  {
    "path": "example/lib/app_settings_page.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter_settings_screens/flutter_settings_screens.dart';\n\nclass AppSettings extends StatefulWidget {\n  @override\n  _AppSettingsState createState() => _AppSettingsState();\n}\n\nclass _AppSettingsState extends State<AppSettings> {\n  @override\n  Widget build(BuildContext context) {\n    return Container(\n      child: SettingsScreen(\n        title: 'Application Settings',\n        children: [\n          SettingsGroup(\n            title: 'Single Choice Settings',\n            children: <Widget>[\n              SwitchSettingsTile(\n                settingKey: 'key-wifi',\n                title: 'Wi-Fi',\n                subtitle: 'Wi-Fi allows interacting with the local network '\n                    'or internet via connecting to a W-Fi router',\n                enabledLabel: 'Enabled',\n                disabledLabel: 'Disabled',\n                leading: Icon(Icons.wifi),\n                onChange: (value) {\n                  debugPrint('key-wifi: $value');\n                },\n              ),\n              CheckboxSettingsTile(\n                settingKey: 'key-blue-tooth',\n                title: 'Bluetooth',\n                subtitle: 'Bluetooth allows interacting with the '\n                    'near by bluetooth enabled devices',\n                enabledLabel: 'Enabled',\n                disabledLabel: 'Disabled',\n                leading: Icon(Icons.bluetooth),\n                onChange: (value) {\n                  debugPrint('key-blue-tooth: $value');\n                },\n              ),\n              SwitchSettingsTile(\n                leading: Icon(Icons.developer_mode),\n                settingKey: 'key-switch-dev-mode',\n                title: 'Developer Settings',\n                onChange: (value) {\n                  debugPrint('key-switch-dev-mod: $value');\n                },\n                childrenIfEnabled: <Widget>[\n                  CheckboxSettingsTile(\n                    leading: Icon(Icons.adb),\n                    settingKey: 'key-is-developer',\n                    title: 'Developer Mode',\n                    defaultValue: true,\n                    onChange: (value) {\n                      debugPrint('key-is-developer: $value');\n                    },\n                  ),\n                  SwitchSettingsTile(\n                    leading: Icon(Icons.usb),\n                    settingKey: 'key-is-usb-debugging',\n                    title: 'USB Debugging',\n                    onChange: (value) {\n                      debugPrint('key-is-usb-debugging: $value');\n                    },\n                  ),\n                  SimpleSettingsTile(\n                    title: 'Root Settings',\n                    subtitle: 'These setting is not accessible',\n                    enabled: false,\n                  ),\n                  SimpleSettingsTile(\n                    title: 'Custom Settings',\n                    subtitle: 'Tap to execute custom callback',\n                    onTap: () => debugPrint('Custom action'),\n                  ),\n                ],\n              ),\n              SimpleSettingsTile(\n                title: 'More Settings',\n                subtitle: 'General App Settings',\n                child: SettingsScreen(\n                  title: 'App Settings',\n                  children: <Widget>[\n                    CheckboxSettingsTile(\n                      leading: Icon(Icons.adb),\n                      settingKey: 'key-is-developer',\n                      title: 'Developer Mode',\n                      onChange: (bool value) {\n                        debugPrint('Developer Mode ${value ? 'on' : 'off'}');\n                      },\n                    ),\n                    SwitchSettingsTile(\n                      leading: Icon(Icons.usb),\n                      settingKey: 'key-is-usb-debugging',\n                      title: 'USB Debugging',\n                      onChange: (value) {\n                        debugPrint('USB Debugging: $value');\n                      },\n                    ),\n                  ],\n                ),\n              ),\n              TextInputSettingsTile(\n                title: 'User Name',\n                settingKey: 'key-user-name',\n                initialValue: 'admin',\n                validator: (String? username) {\n                  if (username != null && username.length > 3) {\n                    return null;\n                  }\n                  return \"User Name can't be smaller than 4 letters\";\n                },\n                borderColor: Colors.blueAccent,\n                errorColor: Colors.deepOrangeAccent,\n              ),\n              TextInputSettingsTile(\n                title: 'password',\n                settingKey: 'key-user-password',\n                obscureText: true,\n                validator: (String? password) {\n                  if (password != null && password.length > 6) {\n                    return null;\n                  }\n                  return \"Password can't be smaller than 7 letters\";\n                },\n                borderColor: Colors.blueAccent,\n                errorColor: Colors.deepOrangeAccent,\n              ),\n              ModalSettingsTile(\n                title: 'Quick setting dialog',\n                subtitle: 'Settings on a dialog',\n                children: <Widget>[\n                  CheckboxSettingsTile(\n                    settingKey: 'key-day-light-savings',\n                    title: 'Daylight Time Saving',\n                    enabledLabel: 'Enabled',\n                    disabledLabel: 'Disabled',\n                    leading: Icon(Icons.timelapse),\n                    onChange: (value) {\n                      debugPrint('key-day-light-saving: $value');\n                    },\n                  ),\n                  SwitchSettingsTile(\n                    settingKey: 'key-dark-mode',\n                    title: 'Dark Mode',\n                    enabledLabel: 'Enabled',\n                    disabledLabel: 'Disabled',\n                    leading: Icon(Icons.palette),\n                    onChange: (value) {\n                      debugPrint('jey-dark-mode: $value');\n                    },\n                  ),\n                ],\n              ),\n              ExpandableSettingsTile(\n                title: 'Quick setting 2',\n                subtitle: 'Expandable Settings',\n                expanded: true,\n                children: <Widget>[\n                  CheckboxSettingsTile(\n                    settingKey: 'key-day-light-savings-2',\n                    title: 'Daylight Time Saving',\n                    enabledLabel: 'Enabled',\n                    disabledLabel: 'Disabled',\n                    leading: Icon(Icons.timelapse),\n                    onChange: (value) {\n                      debugPrint('key-day-light-savings-2: $value');\n                    },\n                  ),\n                  SwitchSettingsTile(\n                    settingKey: 'key-dark-mode-2',\n                    title: 'Dark Mode',\n                    enabledLabel: 'Enabled',\n                    disabledLabel: 'Disabled',\n                    leading: Icon(Icons.palette),\n                    onChange: (value) {\n                      debugPrint('key-dark-mode-2: $value');\n                    },\n                  ),\n                ],\n              ),\n            ],\n          ),\n          SettingsGroup(\n            title: 'Multiple choice settings',\n            children: <Widget>[\n              RadioSettingsTile<int>(\n                title: 'Preferred Sync Period',\n                settingKey: 'key-radio-sync-period',\n                values: <int, String>{\n                  0: 'Never',\n                  1: 'Daily',\n                  7: 'Weekly',\n                  15: 'Fortnight',\n                  30: 'Monthly',\n                },\n                selected: 0,\n                onChange: (value) {\n                  debugPrint('key-radio-sync-period: $value');\n                },\n              ),\n              DropDownSettingsTile<int>(\n                title: 'E-Mail View',\n                settingKey: 'key-dropdown-email-view',\n                values: <int, String>{\n                  2: 'Simple',\n                  3: 'Adjusted',\n                  4: 'Normal',\n                  5: 'Compact',\n                  6: 'Squizzed',\n                },\n                selected: 2,\n                onChange: (value) {\n                  debugPrint('key-dropdown-email-view: $value');\n                },\n              ),\n            ],\n          ),\n          ModalSettingsTile(\n            title: 'Group Settings',\n            subtitle: 'Same group settings but in a dialog',\n            children: <Widget>[\n              SimpleRadioSettingsTile(\n                title: 'Sync Settings',\n                settingKey: 'key-radio-sync-settings',\n                values: <String>[\n                  'Never',\n                  'Daily',\n                  'Weekly',\n                  'Fortnight',\n                  'Monthly',\n                ],\n                selected: 'Daily',\n                onChange: (value) {\n                  debugPrint('key-radio-sync-settings: $value');\n                },\n              ),\n              SimpleDropDownSettingsTile(\n                title: 'Beauty Filter',\n                settingKey: 'key-dropdown-beauty-filter',\n                values: <String>[\n                  'Simple',\n                  'Normal',\n                  'Little Special',\n                  'Special',\n                  'Extra Special',\n                  'Bizarre',\n                  'Horrific',\n                ],\n                selected: 'Special',\n                onChange: (value) {\n                  debugPrint('key-dropdown-beauty-filter: $value');\n                },\n              )\n            ],\n          ),\n          ExpandableSettingsTile(\n            title: 'Expandable Group Settings',\n            subtitle: 'Group of settings (expandable)',\n            children: <Widget>[\n              RadioSettingsTile<double>(\n                title: 'Beauty Filter',\n                settingKey: 'key-radio-beauty-filter-expandable',\n                values: <double, String>{\n                  1.0: 'Simple',\n                  1.5: 'Normal',\n                  2.0: 'Little Special',\n                  2.5: 'Special',\n                  3.0: 'Extra Special',\n                  3.5: 'Bizarre',\n                  4.0: 'Horrific',\n                },\n                selected: 2.5,\n                onChange: (value) {\n                  debugPrint('key-radio-beauty-filter-expandable: $value');\n                },\n              ),\n              DropDownSettingsTile<int>(\n                title: 'Preferred Sync Period',\n                settingKey: 'key-dropdown-sync-period-2',\n                values: <int, String>{\n                  0: 'Never',\n                  1: 'Daily',\n                  7: 'Weekly',\n                  15: 'Fortnight',\n                  30: 'Monthly',\n                },\n                selected: 0,\n                onChange: (value) {\n                  debugPrint('key-dropdown-sync-period-2: $value');\n                },\n              )\n            ],\n          ),\n          SettingsGroup(\n            title: 'Other settings',\n            children: <Widget>[\n              SliderSettingsTile(\n                title: 'Volume [Auto-Adjusting to 20]',\n                settingKey: 'key-slider-volume',\n                defaultValue: 20,\n                min: 0,\n                max: 100,\n                step: 1,\n                leading: Icon(Icons.volume_up),\n                decimalPrecision: 0,\n                onChange: (value) {\n                  debugPrint('\\n===== on change end =====\\n'\n                      'key-slider-volume: $value'\n                      '\\n==========\\n');\n                  Future.delayed(Duration(seconds: 1), () {\n                    // Reset value only if the current value is not 20\n                    if (Settings.getValue<double>('key-slider-volume') != 20) {\n                      debugPrint('\\n===== on change end =====\\n'\n                          'Resetting value to 20'\n                          '\\n==========\\n');\n                      Settings.setValue<double>('key-slider-volume', 20.0,\n                          notify: true);\n                    }\n                  });\n                },\n              ),\n              ColorPickerSettingsTile(\n                settingKey: 'key-color-picker',\n                title: 'Accent Color',\n                defaultValue: Colors.blue,\n                onChange: (value) {\n                  debugPrint('key-color-picker: $value');\n                },\n              )\n            ],\n          ),\n          ModalSettingsTile(\n            title: 'Other settings',\n            subtitle: 'Other Settings in a Dialog',\n            children: <Widget>[\n              SliderSettingsTile(\n                title: 'Custom Ratio',\n                settingKey: 'key-custom-ratio-slider-2',\n                defaultValue: 2.5,\n                min: 1,\n                max: 5,\n                step: 0.1,\n                decimalPrecision: 1,\n                leading: Icon(Icons.aspect_ratio),\n                onChange: (value) {\n                  debugPrint('\\n===== on change =====\\n'\n                      'key-custom-ratio-slider-2: $value'\n                      '\\n==========\\n');\n                },\n                onChangeStart: (value) {\n                  debugPrint('\\n===== on change start =====\\n'\n                      'key-custom-ratio-slider-2: $value'\n                      '\\n==========\\n');\n                },\n                onChangeEnd: (value) {\n                  debugPrint('\\n===== on change end =====\\n'\n                      'key-custom-ratio-slider-2: $value'\n                      '\\n==========\\n');\n                },\n              ),\n              ColorPickerSettingsTile(\n                settingKey: 'key-color-picker-2',\n                title: 'Accent Picker',\n                defaultValue: Colors.blue,\n                onChange: (value) {\n                  debugPrint('key-color-picker-2: $value');\n                },\n              )\n            ],\n          )\n        ],\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "example/lib/cache_provider.dart",
    "content": "import 'package:flutter/foundation.dart';\nimport 'package:flutter/material.dart';\nimport 'package:flutter_settings_screens/flutter_settings_screens.dart';\nimport 'package:hive/hive.dart';\nimport 'package:path_provider/path_provider.dart';\n\n/// A cache access provider class for shared preferences using Hive library\nclass HiveCache extends CacheProvider {\n  Box? _preferences;\n  final String keyName = 'app_preferences';\n\n  @override\n  Future<void> init() async {\n    WidgetsFlutterBinding.ensureInitialized();\n    if (!kIsWeb) {\n      final defaultDirectory = await getApplicationDocumentsDirectory();\n      Hive.init(defaultDirectory.path);\n    }\n    if (Hive.isBoxOpen(keyName)) {\n      _preferences = Hive.box(keyName);\n    } else {\n      _preferences = await Hive.openBox(keyName);\n    }\n  }\n\n  Set get keys => getKeys();\n\n  @override\n  bool? getBool(String key, {bool? defaultValue}) {\n    return _preferences?.get(key);\n  }\n\n  @override\n  double? getDouble(String key, {double? defaultValue}) {\n    return _preferences?.get(key);\n  }\n\n  @override\n  int? getInt(String key, {int? defaultValue}) {\n    return _preferences?.get(key);\n  }\n\n  @override\n  String? getString(String key, {String? defaultValue}) {\n    return _preferences?.get(key);\n  }\n\n  @override\n  Future<void> setBool(String key, bool? value) async {\n    await _preferences?.put(key, value);\n  }\n\n  @override\n  Future<void> setDouble(String key, double? value) async {\n    await _preferences?.put(key, value);\n  }\n\n  @override\n  Future<void> setInt(String key, int? value) async {\n    await _preferences?.put(key, value);\n  }\n\n  @override\n  Future<void> setString(String key, String? value) async {\n    await _preferences?.put(key, value);\n  }\n\n  @override\n  Future<void> setObject<T>(String key, T? value) async {\n    await _preferences?.put(key, value);\n  }\n\n  @override\n  bool containsKey(String key) {\n    return _preferences?.containsKey(key) ?? false;\n  }\n\n  @override\n  Set getKeys() {\n    return _preferences?.keys.toSet() ?? {};\n  }\n\n  @override\n  Future<void> remove(String key) async {\n    if (containsKey(key)) {\n      await _preferences?.delete(key);\n    }\n  }\n\n  @override\n  Future<void> removeAll() async {\n    final keys = getKeys();\n    await _preferences?.deleteAll(keys);\n  }\n\n  @override\n  T? getValue<T>(String key, {T? defaultValue}) {\n    var value = _preferences?.get(key);\n    if (value is T) {\n      return value;\n    }\n    return defaultValue;\n  }\n}\n"
  },
  {
    "path": "example/lib/main.dart",
    "content": "import 'package:flutter/foundation.dart';\nimport 'package:flutter/material.dart';\nimport 'package:flutter_settings_screens/flutter_settings_screens.dart';\n\nimport 'app_settings_page.dart';\nimport 'cache_provider.dart';\n\nvoid main() {\n  initSettings().then((accentColor) {\n    runApp(MyApp(accentColor: accentColor));\n  });\n}\n\nFuture<ValueNotifier<Color>> initSettings() async {\n  await Settings.init(\n    cacheProvider: _isUsingHive ? HiveCache() : SharePreferenceCache(),\n  );\n  final _accentColor = ValueNotifier(Colors.blueAccent);\n  return _accentColor;\n}\n\nbool _isDarkTheme = true;\nbool _isUsingHive = true;\n\nclass MyApp extends StatelessWidget {\n  final ValueNotifier<Color> accentColor;\n\n  const MyApp({Key? key, required this.accentColor}) : super(key: key);\n\n  // This widget is the root of your application.\n  @override\n  Widget build(BuildContext context) {\n    return MyHomePage(\n      title: 'Flutter Demo Home Page',\n      accentColor: accentColor,\n    );\n  }\n}\n\nclass MyHomePage extends StatefulWidget {\n  final String title;\n  final ValueNotifier<Color> accentColor;\n\n  const MyHomePage({\n    Key? key,\n    required this.accentColor,\n    required this.title,\n  }) : super(key: key);\n\n  @override\n  _MyHomePageState createState() => _MyHomePageState();\n}\n\nclass _MyHomePageState extends State<MyHomePage> {\n  @override\n  Widget build(BuildContext context) {\n    return ValueListenableBuilder<Color>(\n      valueListenable: widget.accentColor,\n      builder: (_, color, __) {\n        final _darkTheme = ThemeData.dark();\n        final _lightTheme = ThemeData.light();\n        return MaterialApp(\n          title: 'App Settings Demo',\n          theme: _isDarkTheme\n              ? _darkTheme.copyWith(\n                  colorScheme: _darkTheme.colorScheme.copyWith(\n                    secondary: color,\n                  ),\n                  checkboxTheme: CheckboxThemeData(\n                    fillColor: MaterialStateProperty.resolveWith<Color?>(\n                        (Set<MaterialState> states) {\n                      if (states.contains(MaterialState.disabled)) {\n                        return null;\n                      }\n                      if (states.contains(MaterialState.selected)) {\n                        return color;\n                      }\n                      return null;\n                    }),\n                  ),\n                  radioTheme: RadioThemeData(\n                    fillColor: MaterialStateProperty.resolveWith<Color?>(\n                        (Set<MaterialState> states) {\n                      if (states.contains(MaterialState.disabled)) {\n                        return null;\n                      }\n                      if (states.contains(MaterialState.selected)) {\n                        return color;\n                      }\n                      return null;\n                    }),\n                  ),\n                  switchTheme: SwitchThemeData(\n                    thumbColor: MaterialStateProperty.resolveWith<Color?>(\n                        (Set<MaterialState> states) {\n                      if (states.contains(MaterialState.disabled)) {\n                        return null;\n                      }\n                      if (states.contains(MaterialState.selected)) {\n                        return color;\n                      }\n                      return null;\n                    }),\n                    trackColor: MaterialStateProperty.resolveWith<Color?>(\n                        (Set<MaterialState> states) {\n                      if (states.contains(MaterialState.disabled)) {\n                        return null;\n                      }\n                      if (states.contains(MaterialState.selected)) {\n                        return color;\n                      }\n                      return null;\n                    }),\n                  ),\n                )\n              : _lightTheme.copyWith(\n                  colorScheme: _darkTheme.colorScheme.copyWith(\n                    secondary: color,\n                  ),\n                  checkboxTheme: CheckboxThemeData(\n                    fillColor: MaterialStateProperty.resolveWith<Color?>(\n                        (Set<MaterialState> states) {\n                      if (states.contains(MaterialState.disabled)) {\n                        return null;\n                      }\n                      if (states.contains(MaterialState.selected)) {\n                        return color;\n                      }\n                      return null;\n                    }),\n                  ),\n                  radioTheme: RadioThemeData(\n                    fillColor: MaterialStateProperty.resolveWith<Color?>(\n                        (Set<MaterialState> states) {\n                      if (states.contains(MaterialState.disabled)) {\n                        return null;\n                      }\n                      if (states.contains(MaterialState.selected)) {\n                        return color;\n                      }\n                      return null;\n                    }),\n                  ),\n                  switchTheme: SwitchThemeData(\n                    thumbColor: MaterialStateProperty.resolveWith<Color?>(\n                        (Set<MaterialState> states) {\n                      if (states.contains(MaterialState.disabled)) {\n                        return null;\n                      }\n                      if (states.contains(MaterialState.selected)) {\n                        return color;\n                      }\n                      return null;\n                    }),\n                    trackColor: MaterialStateProperty.resolveWith<Color?>(\n                        (Set<MaterialState> states) {\n                      if (states.contains(MaterialState.disabled)) {\n                        return null;\n                      }\n                      if (states.contains(MaterialState.selected)) {\n                        return color;\n                      }\n                      return null;\n                    }),\n                  ),\n                ),\n          home: Scaffold(\n            appBar: AppBar(\n              title: Text(widget.title),\n            ),\n            body: Center(\n              child: Column(\n                children: <Widget>[\n                  _buildThemeSwitch(context),\n                  _buildPreferenceSwitch(context),\n                  SizedBox(\n                    height: 50.0,\n                  ),\n                  AppBody(),\n                ],\n              ),\n            ),\n          ),\n        );\n      },\n    );\n  }\n\n  Widget _buildPreferenceSwitch(BuildContext context) {\n    return Row(\n      mainAxisAlignment: MainAxisAlignment.spaceEvenly,\n      children: <Widget>[\n        Text('Shared Pref'),\n        Switch(\n            activeColor: Theme.of(context).colorScheme.secondary,\n            value: _isUsingHive,\n            onChanged: (newVal) {\n              if (kIsWeb) {\n                return;\n              }\n              _isUsingHive = newVal;\n              setState(() {\n                initSettings();\n              });\n            }),\n        Text('Hive Storage'),\n      ],\n    );\n  }\n\n  Widget _buildThemeSwitch(BuildContext context) {\n    return Row(\n      mainAxisAlignment: MainAxisAlignment.spaceEvenly,\n      children: <Widget>[\n        Text('Light Theme'),\n        Switch(\n            activeColor: Theme.of(context).colorScheme.secondary,\n            value: _isDarkTheme,\n            onChanged: (newVal) {\n              _isDarkTheme = newVal;\n              setState(() {});\n            }),\n        Text('Dark Theme'),\n      ],\n    );\n  }\n}\n\nclass AppBody extends StatefulWidget {\n  @override\n  _AppBodyState createState() => _AppBodyState();\n}\n\nclass _AppBodyState extends State<AppBody> {\n  @override\n  Widget build(BuildContext context) {\n    return Column(\n      children: <Widget>[\n        _buildClearCacheButton(context),\n        SizedBox(\n          height: 25.0,\n        ),\n        ElevatedButton(\n          onPressed: () {\n            openAppSettings(context);\n          },\n          child: Text('Start Demo'),\n        ),\n      ],\n    );\n  }\n\n  void openAppSettings(BuildContext context) {\n    Navigator.of(context).push(MaterialPageRoute(\n      builder: (context) => AppSettings(),\n    ));\n  }\n\n  Widget _buildClearCacheButton(BuildContext context) {\n    return ElevatedButton(\n      onPressed: () {\n        Settings.clearCache();\n        showSnackBar(\n          context,\n          'Cache cleared for selected cache.',\n        );\n      },\n      child: Text('Clear selected Cache'),\n    );\n  }\n}\n\nvoid showSnackBar(BuildContext context, String message) {\n  ScaffoldMessenger.of(context).showSnackBar(\n    SnackBar(\n      content: Text(\n        message,\n        style: TextStyle(\n          color: Colors.white,\n        ),\n      ),\n      backgroundColor: Theme.of(context).primaryColor,\n    ),\n  );\n}\n"
  },
  {
    "path": "example/macos/.gitignore",
    "content": "# Flutter-related\n**/Flutter/ephemeral/\n**/Pods/\n\n# Xcode-related\n**/dgph\n**/xcuserdata/\n"
  },
  {
    "path": "example/macos/Flutter/Flutter-Debug.xcconfig",
    "content": "#include? \"Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig\"\n#include \"ephemeral/Flutter-Generated.xcconfig\"\n"
  },
  {
    "path": "example/macos/Flutter/Flutter-Release.xcconfig",
    "content": "#include? \"Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig\"\n#include \"ephemeral/Flutter-Generated.xcconfig\"\n"
  },
  {
    "path": "example/macos/Flutter/GeneratedPluginRegistrant.swift",
    "content": "//\n//  Generated file. Do not edit.\n//\n\nimport FlutterMacOS\nimport Foundation\n\nimport path_provider_foundation\nimport shared_preferences_foundation\n\nfunc RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {\n  PathProviderPlugin.register(with: registry.registrar(forPlugin: \"PathProviderPlugin\"))\n  SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: \"SharedPreferencesPlugin\"))\n}\n"
  },
  {
    "path": "example/macos/Podfile",
    "content": "platform :osx, '10.11'\n\n# CocoaPods analytics sends network stats synchronously affecting flutter build latency.\nENV['COCOAPODS_DISABLE_STATS'] = 'true'\n\nproject 'Runner', {\n  'Debug' => :debug,\n  'Profile' => :release,\n  'Release' => :release,\n}\n\ndef flutter_root\n  generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__)\n  unless File.exist?(generated_xcode_build_settings_path)\n    raise \"#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \\\"flutter pub get\\\" is executed first\"\n  end\n\n  File.foreach(generated_xcode_build_settings_path) do |line|\n    matches = line.match(/FLUTTER_ROOT\\=(.*)/)\n    return matches[1].strip if matches\n  end\n  raise \"FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \\\"flutter pub get\\\"\"\nend\n\nrequire File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)\n\nflutter_macos_podfile_setup\n\ntarget 'Runner' do\n  use_frameworks!\n  use_modular_headers!\n\n  flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))\nend\n\npost_install do |installer|\n  installer.pods_project.targets.each do |target|\n    flutter_additional_macos_build_settings(target)\n  end\nend\n"
  },
  {
    "path": "example/macos/Runner/AppDelegate.swift",
    "content": "import Cocoa\nimport FlutterMacOS\n\n@NSApplicationMain\nclass AppDelegate: FlutterAppDelegate {\n  override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {\n    return true\n  }\n}\n"
  },
  {
    "path": "example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\": [\n    {\n      \"size\": \"16x16\",\n      \"idiom\": \"mac\",\n      \"filename\": \"app_icon_16.png\",\n      \"scale\": \"1x\"\n    },\n    {\n      \"size\": \"16x16\",\n      \"idiom\": \"mac\",\n      \"filename\": \"app_icon_32.png\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"32x32\",\n      \"idiom\": \"mac\",\n      \"filename\": \"app_icon_32.png\",\n      \"scale\": \"1x\"\n    },\n    {\n      \"size\": \"32x32\",\n      \"idiom\": \"mac\",\n      \"filename\": \"app_icon_64.png\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"128x128\",\n      \"idiom\": \"mac\",\n      \"filename\": \"app_icon_128.png\",\n      \"scale\": \"1x\"\n    },\n    {\n      \"size\": \"128x128\",\n      \"idiom\": \"mac\",\n      \"filename\": \"app_icon_256.png\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"256x256\",\n      \"idiom\": \"mac\",\n      \"filename\": \"app_icon_256.png\",\n      \"scale\": \"1x\"\n    },\n    {\n      \"size\": \"256x256\",\n      \"idiom\": \"mac\",\n      \"filename\": \"app_icon_512.png\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"512x512\",\n      \"idiom\": \"mac\",\n      \"filename\": \"app_icon_512.png\",\n      \"scale\": \"1x\"\n    },\n    {\n      \"size\": \"512x512\",\n      \"idiom\": \"mac\",\n      \"filename\": \"app_icon_1024.png\",\n      \"scale\": \"2x\"\n    }\n  ],\n  \"info\": {\n    \"version\": 1,\n    \"author\": \"xcode\"\n  }\n}\n"
  },
  {
    "path": "example/macos/Runner/Base.lproj/MainMenu.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"14490.70\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14490.70\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\" customClass=\"NSApplication\">\n            <connections>\n                <outlet property=\"delegate\" destination=\"Voe-Tx-rLC\" id=\"GzC-gU-4Uq\"/>\n            </connections>\n        </customObject>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customObject id=\"Voe-Tx-rLC\" customClass=\"AppDelegate\" customModule=\"Runner\" customModuleProvider=\"target\">\n            <connections>\n                <outlet property=\"applicationMenu\" destination=\"uQy-DD-JDr\" id=\"XBo-yE-nKs\"/>\n                <outlet property=\"mainFlutterWindow\" destination=\"QvC-M9-y7g\" id=\"gIp-Ho-8D9\"/>\n            </connections>\n        </customObject>\n        <customObject id=\"YLy-65-1bz\" customClass=\"NSFontManager\"/>\n        <menu title=\"Main Menu\" systemMenu=\"main\" id=\"AYu-sK-qS6\">\n            <items>\n                <menuItem title=\"APP_NAME\" id=\"1Xt-HY-uBw\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <menu key=\"submenu\" title=\"APP_NAME\" systemMenu=\"apple\" id=\"uQy-DD-JDr\">\n                        <items>\n                            <menuItem title=\"About APP_NAME\" id=\"5kV-Vb-QxS\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <connections>\n                                    <action selector=\"orderFrontStandardAboutPanel:\" target=\"-1\" id=\"Exp-CZ-Vem\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem isSeparatorItem=\"YES\" id=\"VOq-y0-SEH\"/>\n                            <menuItem title=\"Preferences…\" keyEquivalent=\",\" id=\"BOF-NM-1cW\"/>\n                            <menuItem isSeparatorItem=\"YES\" id=\"wFC-TO-SCJ\"/>\n                            <menuItem title=\"Services\" id=\"NMo-om-nkz\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Services\" systemMenu=\"services\" id=\"hz9-B4-Xy5\"/>\n                            </menuItem>\n                            <menuItem isSeparatorItem=\"YES\" id=\"4je-JR-u6R\"/>\n                            <menuItem title=\"Hide APP_NAME\" keyEquivalent=\"h\" id=\"Olw-nP-bQN\">\n                                <connections>\n                                    <action selector=\"hide:\" target=\"-1\" id=\"PnN-Uc-m68\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Hide Others\" keyEquivalent=\"h\" id=\"Vdr-fp-XzO\">\n                                <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                <connections>\n                                    <action selector=\"hideOtherApplications:\" target=\"-1\" id=\"VT4-aY-XCT\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Show All\" id=\"Kd2-mp-pUS\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <connections>\n                                    <action selector=\"unhideAllApplications:\" target=\"-1\" id=\"Dhg-Le-xox\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem isSeparatorItem=\"YES\" id=\"kCx-OE-vgT\"/>\n                            <menuItem title=\"Quit APP_NAME\" keyEquivalent=\"q\" id=\"4sb-4s-VLi\">\n                                <connections>\n                                    <action selector=\"terminate:\" target=\"-1\" id=\"Te7-pn-YzF\"/>\n                                </connections>\n                            </menuItem>\n                        </items>\n                    </menu>\n                </menuItem>\n                <menuItem title=\"Edit\" id=\"5QF-Oa-p0T\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <menu key=\"submenu\" title=\"Edit\" id=\"W48-6f-4Dl\">\n                        <items>\n                            <menuItem title=\"Undo\" keyEquivalent=\"z\" id=\"dRJ-4n-Yzg\">\n                                <connections>\n                                    <action selector=\"undo:\" target=\"-1\" id=\"M6e-cu-g7V\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Redo\" keyEquivalent=\"Z\" id=\"6dh-zS-Vam\">\n                                <connections>\n                                    <action selector=\"redo:\" target=\"-1\" id=\"oIA-Rs-6OD\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem isSeparatorItem=\"YES\" id=\"WRV-NI-Exz\"/>\n                            <menuItem title=\"Cut\" keyEquivalent=\"x\" id=\"uRl-iY-unG\">\n                                <connections>\n                                    <action selector=\"cut:\" target=\"-1\" id=\"YJe-68-I9s\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Copy\" keyEquivalent=\"c\" id=\"x3v-GG-iWU\">\n                                <connections>\n                                    <action selector=\"copy:\" target=\"-1\" id=\"G1f-GL-Joy\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Paste\" keyEquivalent=\"v\" id=\"gVA-U4-sdL\">\n                                <connections>\n                                    <action selector=\"paste:\" target=\"-1\" id=\"UvS-8e-Qdg\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Paste and Match Style\" keyEquivalent=\"V\" id=\"WeT-3V-zwk\">\n                                <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                <connections>\n                                    <action selector=\"pasteAsPlainText:\" target=\"-1\" id=\"cEh-KX-wJQ\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Delete\" id=\"pa3-QI-u2k\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <connections>\n                                    <action selector=\"delete:\" target=\"-1\" id=\"0Mk-Ml-PaM\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Select All\" keyEquivalent=\"a\" id=\"Ruw-6m-B2m\">\n                                <connections>\n                                    <action selector=\"selectAll:\" target=\"-1\" id=\"VNm-Mi-diN\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem isSeparatorItem=\"YES\" id=\"uyl-h8-XO2\"/>\n                            <menuItem title=\"Find\" id=\"4EN-yA-p0u\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Find\" id=\"1b7-l0-nxx\">\n                                    <items>\n                                        <menuItem title=\"Find…\" tag=\"1\" keyEquivalent=\"f\" id=\"Xz5-n4-O0W\">\n                                            <connections>\n                                                <action selector=\"performFindPanelAction:\" target=\"-1\" id=\"cD7-Qs-BN4\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Find and Replace…\" tag=\"12\" keyEquivalent=\"f\" id=\"YEy-JH-Tfz\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                            <connections>\n                                                <action selector=\"performFindPanelAction:\" target=\"-1\" id=\"WD3-Gg-5AJ\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Find Next\" tag=\"2\" keyEquivalent=\"g\" id=\"q09-fT-Sye\">\n                                            <connections>\n                                                <action selector=\"performFindPanelAction:\" target=\"-1\" id=\"NDo-RZ-v9R\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Find Previous\" tag=\"3\" keyEquivalent=\"G\" id=\"OwM-mh-QMV\">\n                                            <connections>\n                                                <action selector=\"performFindPanelAction:\" target=\"-1\" id=\"HOh-sY-3ay\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Use Selection for Find\" tag=\"7\" keyEquivalent=\"e\" id=\"buJ-ug-pKt\">\n                                            <connections>\n                                                <action selector=\"performFindPanelAction:\" target=\"-1\" id=\"U76-nv-p5D\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Jump to Selection\" keyEquivalent=\"j\" id=\"S0p-oC-mLd\">\n                                            <connections>\n                                                <action selector=\"centerSelectionInVisibleArea:\" target=\"-1\" id=\"IOG-6D-g5B\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"Spelling and Grammar\" id=\"Dv1-io-Yv7\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Spelling\" id=\"3IN-sU-3Bg\">\n                                    <items>\n                                        <menuItem title=\"Show Spelling and Grammar\" keyEquivalent=\":\" id=\"HFo-cy-zxI\">\n                                            <connections>\n                                                <action selector=\"showGuessPanel:\" target=\"-1\" id=\"vFj-Ks-hy3\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Check Document Now\" keyEquivalent=\";\" id=\"hz2-CU-CR7\">\n                                            <connections>\n                                                <action selector=\"checkSpelling:\" target=\"-1\" id=\"fz7-VC-reM\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"bNw-od-mp5\"/>\n                                        <menuItem title=\"Check Spelling While Typing\" id=\"rbD-Rh-wIN\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"toggleContinuousSpellChecking:\" target=\"-1\" id=\"7w6-Qz-0kB\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Check Grammar With Spelling\" id=\"mK6-2p-4JG\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"toggleGrammarChecking:\" target=\"-1\" id=\"muD-Qn-j4w\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Correct Spelling Automatically\" id=\"78Y-hA-62v\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"toggleAutomaticSpellingCorrection:\" target=\"-1\" id=\"2lM-Qi-WAP\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"Substitutions\" id=\"9ic-FL-obx\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Substitutions\" id=\"FeM-D8-WVr\">\n                                    <items>\n                                        <menuItem title=\"Show Substitutions\" id=\"z6F-FW-3nz\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"orderFrontSubstitutionsPanel:\" target=\"-1\" id=\"oku-mr-iSq\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"gPx-C9-uUO\"/>\n                                        <menuItem title=\"Smart Copy/Paste\" id=\"9yt-4B-nSM\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"toggleSmartInsertDelete:\" target=\"-1\" id=\"3IJ-Se-DZD\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Smart Quotes\" id=\"hQb-2v-fYv\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"toggleAutomaticQuoteSubstitution:\" target=\"-1\" id=\"ptq-xd-QOA\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Smart Dashes\" id=\"rgM-f4-ycn\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"toggleAutomaticDashSubstitution:\" target=\"-1\" id=\"oCt-pO-9gS\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Smart Links\" id=\"cwL-P1-jid\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"toggleAutomaticLinkDetection:\" target=\"-1\" id=\"Gip-E3-Fov\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Data Detectors\" id=\"tRr-pd-1PS\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"toggleAutomaticDataDetection:\" target=\"-1\" id=\"R1I-Nq-Kbl\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Text Replacement\" id=\"HFQ-gK-NFA\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"toggleAutomaticTextReplacement:\" target=\"-1\" id=\"DvP-Fe-Py6\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"Transformations\" id=\"2oI-Rn-ZJC\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Transformations\" id=\"c8a-y6-VQd\">\n                                    <items>\n                                        <menuItem title=\"Make Upper Case\" id=\"vmV-6d-7jI\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"uppercaseWord:\" target=\"-1\" id=\"sPh-Tk-edu\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Make Lower Case\" id=\"d9M-CD-aMd\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"lowercaseWord:\" target=\"-1\" id=\"iUZ-b5-hil\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Capitalize\" id=\"UEZ-Bs-lqG\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"capitalizeWord:\" target=\"-1\" id=\"26H-TL-nsh\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"Speech\" id=\"xrE-MZ-jX0\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Speech\" id=\"3rS-ZA-NoH\">\n                                    <items>\n                                        <menuItem title=\"Start Speaking\" id=\"Ynk-f8-cLZ\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"startSpeaking:\" target=\"-1\" id=\"654-Ng-kyl\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Stop Speaking\" id=\"Oyz-dy-DGm\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"stopSpeaking:\" target=\"-1\" id=\"dX8-6p-jy9\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                        </items>\n                    </menu>\n                </menuItem>\n                <menuItem title=\"View\" id=\"H8h-7b-M4v\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <menu key=\"submenu\" title=\"View\" id=\"HyV-fh-RgO\">\n                        <items>\n                            <menuItem title=\"Enter Full Screen\" keyEquivalent=\"f\" id=\"4J7-dP-txa\">\n                                <modifierMask key=\"keyEquivalentModifierMask\" control=\"YES\" command=\"YES\"/>\n                                <connections>\n                                    <action selector=\"toggleFullScreen:\" target=\"-1\" id=\"dU3-MA-1Rq\"/>\n                                </connections>\n                            </menuItem>\n                        </items>\n                    </menu>\n                </menuItem>\n                <menuItem title=\"Window\" id=\"aUF-d1-5bR\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <menu key=\"submenu\" title=\"Window\" systemMenu=\"window\" id=\"Td7-aD-5lo\">\n                        <items>\n                            <menuItem title=\"Minimize\" keyEquivalent=\"m\" id=\"OY7-WF-poV\">\n                                <connections>\n                                    <action selector=\"performMiniaturize:\" target=\"-1\" id=\"VwT-WD-YPe\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Zoom\" id=\"R4o-n2-Eq4\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <connections>\n                                    <action selector=\"performZoom:\" target=\"-1\" id=\"DIl-cC-cCs\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem isSeparatorItem=\"YES\" id=\"eu3-7i-yIM\"/>\n                            <menuItem title=\"Bring All to Front\" id=\"LE2-aR-0XJ\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <connections>\n                                    <action selector=\"arrangeInFront:\" target=\"-1\" id=\"DRN-fu-gQh\"/>\n                                </connections>\n                            </menuItem>\n                        </items>\n                    </menu>\n                </menuItem>\n                <menuItem title=\"Help\" id=\"EPT-qC-fAb\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <menu key=\"submenu\" title=\"Help\" systemMenu=\"help\" id=\"rJ0-wn-3NY\"/>\n                </menuItem>\n            </items>\n            <point key=\"canvasLocation\" x=\"142\" y=\"-258\"/>\n        </menu>\n        <window title=\"APP_NAME\" allowsToolTipsWhenApplicationIsInactive=\"NO\" autorecalculatesKeyViewLoop=\"NO\" releasedWhenClosed=\"NO\" animationBehavior=\"default\" id=\"QvC-M9-y7g\" customClass=\"MainFlutterWindow\" customModule=\"Runner\" customModuleProvider=\"target\">\n            <windowStyleMask key=\"styleMask\" titled=\"YES\" closable=\"YES\" miniaturizable=\"YES\" resizable=\"YES\"/>\n            <rect key=\"contentRect\" x=\"335\" y=\"390\" width=\"800\" height=\"600\"/>\n            <rect key=\"screenRect\" x=\"0.0\" y=\"0.0\" width=\"2560\" height=\"1577\"/>\n            <view key=\"contentView\" wantsLayer=\"YES\" id=\"EiT-Mj-1SZ\">\n                <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"800\" height=\"600\"/>\n                <autoresizingMask key=\"autoresizingMask\"/>\n            </view>\n        </window>\n    </objects>\n</document>\n"
  },
  {
    "path": "example/macos/Runner/Configs/AppInfo.xcconfig",
    "content": "// Application-level settings for the Runner target.\n//\n// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the\n// future. If not, the values below would default to using the project name when this becomes a\n// 'flutter create' template.\n\n// The application's name. By default this is also the title of the Flutter window.\nPRODUCT_NAME = example\n\n// The application's bundle identifier\nPRODUCT_BUNDLE_IDENTIFIER = com.example.example\n\n// The copyright displayed in application information\nPRODUCT_COPYRIGHT = Copyright © 2022 com.example. All rights reserved.\n"
  },
  {
    "path": "example/macos/Runner/Configs/Debug.xcconfig",
    "content": "#include \"../../Flutter/Flutter-Debug.xcconfig\"\n#include \"Warnings.xcconfig\"\n"
  },
  {
    "path": "example/macos/Runner/Configs/Release.xcconfig",
    "content": "#include \"../../Flutter/Flutter-Release.xcconfig\"\n#include \"Warnings.xcconfig\"\n"
  },
  {
    "path": "example/macos/Runner/Configs/Warnings.xcconfig",
    "content": "WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings\nGCC_WARN_UNDECLARED_SELECTOR = YES\nCLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES\nCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE\nCLANG_WARN__DUPLICATE_METHOD_MATCH = YES\nCLANG_WARN_PRAGMA_PACK = YES\nCLANG_WARN_STRICT_PROTOTYPES = YES\nCLANG_WARN_COMMA = YES\nGCC_WARN_STRICT_SELECTOR_MATCH = YES\nCLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES\nCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES\nGCC_WARN_SHADOW = YES\nCLANG_WARN_UNREACHABLE_CODE = YES\n"
  },
  {
    "path": "example/macos/Runner/DebugProfile.entitlements",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>com.apple.security.app-sandbox</key>\n\t<true/>\n\t<key>com.apple.security.cs.allow-jit</key>\n\t<true/>\n\t<key>com.apple.security.network.server</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "example/macos/Runner/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIconFile</key>\n\t<string></string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>$(FLUTTER_BUILD_NAME)</string>\n\t<key>CFBundleVersion</key>\n\t<string>$(FLUTTER_BUILD_NUMBER)</string>\n\t<key>LSMinimumSystemVersion</key>\n\t<string>$(MACOSX_DEPLOYMENT_TARGET)</string>\n\t<key>NSHumanReadableCopyright</key>\n\t<string>$(PRODUCT_COPYRIGHT)</string>\n\t<key>NSMainNibFile</key>\n\t<string>MainMenu</string>\n\t<key>NSPrincipalClass</key>\n\t<string>NSApplication</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "example/macos/Runner/MainFlutterWindow.swift",
    "content": "import Cocoa\nimport FlutterMacOS\n\nclass MainFlutterWindow: NSWindow {\n  override func awakeFromNib() {\n    let flutterViewController = FlutterViewController.init()\n    let windowFrame = self.frame\n    self.contentViewController = flutterViewController\n    self.setFrame(windowFrame, display: true)\n\n    RegisterGeneratedPlugins(registry: flutterViewController)\n\n    super.awakeFromNib()\n  }\n}\n"
  },
  {
    "path": "example/macos/Runner/Release.entitlements",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>com.apple.security.app-sandbox</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "example/macos/Runner.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 51;\n\tobjects = {\n\n/* Begin PBXAggregateTarget section */\n\t\t33CC111A2044C6BA0003C045 /* Flutter Assemble */ = {\n\t\t\tisa = PBXAggregateTarget;\n\t\t\tbuildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget \"Flutter Assemble\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t33CC111E2044C6BF0003C045 /* ShellScript */,\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = \"Flutter Assemble\";\n\t\t\tproductName = FLX;\n\t\t};\n/* End PBXAggregateTarget section */\n\n/* Begin PBXBuildFile section */\n\t\t335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; };\n\t\t33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; };\n\t\t33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };\n\t\t33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };\n\t\t33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\t33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 33CC10E52044A3C60003C045 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 33CC111A2044C6BA0003C045;\n\t\t\tremoteInfo = FLX;\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXCopyFilesBuildPhase section */\n\t\t33CC110E2044A8840003C045 /* Bundle Framework */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = \"\";\n\t\t\tdstSubfolderSpec = 10;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tname = \"Bundle Framework\";\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXCopyFilesBuildPhase section */\n\n/* Begin PBXFileReference section */\n\t\t333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = \"<group>\"; };\n\t\t335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = \"<group>\"; };\n\t\t33CC10ED2044A3C60003C045 /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = \"example.app\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\t33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = \"<group>\"; };\n\t\t33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = \"<group>\"; };\n\t\t33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = \"<group>\"; };\n\t\t33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = \"Flutter-Debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = \"Flutter-Release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = \"Flutter-Generated.xcconfig\"; path = \"ephemeral/Flutter-Generated.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = \"<group>\"; };\n\t\t33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = \"<group>\"; };\n\t\t33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = \"<group>\"; };\n\t\t7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = \"<group>\"; };\n\t\t9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t33CC10EA2044A3C60003C045 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t33BA886A226E78AF003329D5 /* Configs */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t33E5194F232828860026EE4D /* AppInfo.xcconfig */,\n\t\t\t\t9740EEB21CF90195004384FC /* Debug.xcconfig */,\n\t\t\t\t7AFA3C8E1D35360C0083082E /* Release.xcconfig */,\n\t\t\t\t333000ED22D3DE5D00554162 /* Warnings.xcconfig */,\n\t\t\t);\n\t\t\tpath = Configs;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t33CC10E42044A3C60003C045 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t33FAB671232836740065AC1E /* Runner */,\n\t\t\t\t33CEB47122A05771004F2AC0 /* Flutter */,\n\t\t\t\t33CC10EE2044A3C60003C045 /* Products */,\n\t\t\t\tD73912EC22F37F3D000D13A0 /* Frameworks */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t33CC10EE2044A3C60003C045 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t33CC10ED2044A3C60003C045 /* example.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t33CC11242044D66E0003C045 /* Resources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t33CC10F22044A3C60003C045 /* Assets.xcassets */,\n\t\t\t\t33CC10F42044A3C60003C045 /* MainMenu.xib */,\n\t\t\t\t33CC10F72044A3C60003C045 /* Info.plist */,\n\t\t\t);\n\t\t\tname = Resources;\n\t\t\tpath = ..;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t33CEB47122A05771004F2AC0 /* Flutter */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */,\n\t\t\t\t33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */,\n\t\t\t\t33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */,\n\t\t\t\t33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */,\n\t\t\t);\n\t\t\tpath = Flutter;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t33FAB671232836740065AC1E /* Runner */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t33CC10F02044A3C60003C045 /* AppDelegate.swift */,\n\t\t\t\t33CC11122044BFA00003C045 /* MainFlutterWindow.swift */,\n\t\t\t\t33E51913231747F40026EE4D /* DebugProfile.entitlements */,\n\t\t\t\t33E51914231749380026EE4D /* Release.entitlements */,\n\t\t\t\t33CC11242044D66E0003C045 /* Resources */,\n\t\t\t\t33BA886A226E78AF003329D5 /* Configs */,\n\t\t\t);\n\t\t\tpath = Runner;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tD73912EC22F37F3D000D13A0 /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t33CC10EC2044A3C60003C045 /* Runner */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget \"Runner\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t33CC10E92044A3C60003C045 /* Sources */,\n\t\t\t\t33CC10EA2044A3C60003C045 /* Frameworks */,\n\t\t\t\t33CC10EB2044A3C60003C045 /* Resources */,\n\t\t\t\t33CC110E2044A8840003C045 /* Bundle Framework */,\n\t\t\t\t3399D490228B24CF009A79C7 /* ShellScript */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t33CC11202044C79F0003C045 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = Runner;\n\t\t\tproductName = Runner;\n\t\t\tproductReference = 33CC10ED2044A3C60003C045 /* example.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t33CC10E52044A3C60003C045 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 0920;\n\t\t\t\tLastUpgradeCheck = 1300;\n\t\t\t\tORGANIZATIONNAME = \"\";\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t33CC10EC2044A3C60003C045 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 9.2;\n\t\t\t\t\t\tLastSwiftMigration = 1100;\n\t\t\t\t\t\tProvisioningStyle = Automatic;\n\t\t\t\t\t\tSystemCapabilities = {\n\t\t\t\t\t\t\tcom.apple.Sandbox = {\n\t\t\t\t\t\t\t\tenabled = 1;\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t};\n\t\t\t\t\t};\n\t\t\t\t\t33CC111A2044C6BA0003C045 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 9.2;\n\t\t\t\t\t\tProvisioningStyle = Manual;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject \"Runner\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 33CC10E42044A3C60003C045;\n\t\t\tproductRefGroup = 33CC10EE2044A3C60003C045 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t33CC10EC2044A3C60003C045 /* Runner */,\n\t\t\t\t33CC111A2044C6BA0003C045 /* Flutter Assemble */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t33CC10EB2044A3C60003C045 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */,\n\t\t\t\t33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\t3399D490228B24CF009A79C7 /* ShellScript */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"echo \\\"$PRODUCT_NAME.app\\\" > \\\"$PROJECT_DIR\\\"/Flutter/ephemeral/.app_filename && \\\"$FLUTTER_ROOT\\\"/packages/flutter_tools/bin/macos_assemble.sh embed\\n\";\n\t\t};\n\t\t33CC111E2044C6BF0003C045 /* ShellScript */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t\tFlutter/ephemeral/FlutterInputs.xcfilelist,\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\tFlutter/ephemeral/tripwire,\n\t\t\t);\n\t\t\toutputFileListPaths = (\n\t\t\t\tFlutter/ephemeral/FlutterOutputs.xcfilelist,\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"\\\"$FLUTTER_ROOT\\\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire\";\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t33CC10E92044A3C60003C045 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */,\n\t\t\t\t33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */,\n\t\t\t\t335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXTargetDependency section */\n\t\t33CC11202044C79F0003C045 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 33CC111A2044C6BA0003C045 /* Flutter Assemble */;\n\t\t\ttargetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin PBXVariantGroup section */\n\t\t33CC10F42044A3C60003C045 /* MainMenu.xib */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t33CC10F52044A3C60003C045 /* Base */,\n\t\t\t);\n\t\t\tname = MainMenu.xib;\n\t\t\tpath = Runner;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t338D0CE9231458BD00FA5F75 /* Profile */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"-\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.11;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tSDKROOT = macosx;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t};\n\t\t\tname = Profile;\n\t\t};\n\t\t338D0CEA231458BD00FA5F75 /* Profile */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tINFOPLIST_FILE = Runner/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/../Frameworks\",\n\t\t\t\t);\n\t\t\t\tPROVISIONING_PROFILE_SPECIFIER = \"\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t};\n\t\t\tname = Profile;\n\t\t};\n\t\t338D0CEB231458BD00FA5F75 /* Profile */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCODE_SIGN_STYLE = Manual;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Profile;\n\t\t};\n\t\t33CC10F92044A3C60003C045 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"-\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.11;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = macosx;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t33CC10FA2044A3C60003C045 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"-\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.11;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tSDKROOT = macosx;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t33CC10FC2044A3C60003C045 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tINFOPLIST_FILE = Runner/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/../Frameworks\",\n\t\t\t\t);\n\t\t\t\tPROVISIONING_PROFILE_SPECIFIER = \"\";\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t33CC10FD2044A3C60003C045 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tINFOPLIST_FILE = Runner/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/../Frameworks\",\n\t\t\t\t);\n\t\t\t\tPROVISIONING_PROFILE_SPECIFIER = \"\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t33CC111C2044C6BA0003C045 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCODE_SIGN_STYLE = Manual;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t33CC111D2044C6BA0003C045 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t33CC10E82044A3C60003C045 /* Build configuration list for PBXProject \"Runner\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t33CC10F92044A3C60003C045 /* Debug */,\n\t\t\t\t33CC10FA2044A3C60003C045 /* Release */,\n\t\t\t\t338D0CE9231458BD00FA5F75 /* Profile */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget \"Runner\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t33CC10FC2044A3C60003C045 /* Debug */,\n\t\t\t\t33CC10FD2044A3C60003C045 /* Release */,\n\t\t\t\t338D0CEA231458BD00FA5F75 /* Profile */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget \"Flutter Assemble\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t33CC111C2044C6BA0003C045 /* Debug */,\n\t\t\t\t33CC111D2044C6BA0003C045 /* Release */,\n\t\t\t\t338D0CEB231458BD00FA5F75 /* Profile */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 33CC10E52044A3C60003C045 /* Project object */;\n}\n"
  },
  {
    "path": "example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEDidComputeMac32BitWarning</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1300\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"33CC10EC2044A3C60003C045\"\n               BuildableName = \"example.app\"\n               BlueprintName = \"Runner\"\n               ReferencedContainer = \"container:Runner.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"33CC10EC2044A3C60003C045\"\n            BuildableName = \"example.app\"\n            BlueprintName = \"Runner\"\n            ReferencedContainer = \"container:Runner.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"33CC10EC2044A3C60003C045\"\n            BuildableName = \"example.app\"\n            BlueprintName = \"Runner\"\n            ReferencedContainer = \"container:Runner.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Profile\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"33CC10EC2044A3C60003C045\"\n            BuildableName = \"example.app\"\n            BlueprintName = \"Runner\"\n            ReferencedContainer = \"container:Runner.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "example/macos/Runner.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"group:Runner.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEDidComputeMac32BitWarning</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "example/pubspec.yaml",
    "content": "name: flutter_settings_screens_example\ndescription: Demonstrates flutter_settings_screens plugin features.\npublish_to: 'none'\n\nenvironment:\n  sdk: '>=3.2.4 <4.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: ^1.0.0\n\n  #library to store the preference/settings using hive library\n  hive_flutter: ^1.0.0\n\ndev_dependencies:\n  flutter_test:\n    sdk: flutter\n\n  flutter_settings_screens:\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\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//\n//import 'package:flutter/material.dart';\n//import 'package:flutter_test/flutter_test.dart';\n//\n//import 'package:flutter_settings_screens_example/main.dart';\n//\n//void main() {\n//  testWidgets('Verify Platform version', (WidgetTester tester) async {\n//    // Build our app and trigger a frame.\n//    await tester.pumpWidget(MyApp());\n//\n//    // Verify that platform version is retrieved.\n//    expect(\n//      find.byWidgetPredicate(\n//        (Widget widget) => widget is Text &&\n//                           widget.data.startsWith('Running on:'),\n//      ),\n//      findsOneWidget,\n//    );\n//  });\n//}\n"
  },
  {
    "path": "example/web/index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n  <!--\n    If you are serving your web app in a path other than the root, change the\n    href value below to reflect the base path you are serving from.\n\n    The path provided below has to start and end with a slash \"/\" in order for\n    it to work correctly.\n\n    For more details:\n    * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base\n\n    This is a placeholder for base href that will be replaced by the value of\n    the `--base-href` argument provided to `flutter build`.\n  -->\n  <base href=\"$FLUTTER_BASE_HREF\">\n\n  <meta charset=\"UTF-8\">\n  <meta content=\"IE=Edge\" http-equiv=\"X-UA-Compatible\">\n  <meta content=\"A new Flutter project.\" name=\"description\">\n\n  <!-- iOS meta tags & icons -->\n  <meta content=\"yes\" name=\"apple-mobile-web-app-capable\">\n  <meta content=\"black\" name=\"apple-mobile-web-app-status-bar-style\">\n  <meta content=\"example\" name=\"apple-mobile-web-app-title\">\n  <link href=\"icons/Icon-192.png\" rel=\"apple-touch-icon\">\n\n  <!-- Favicon -->\n  <link href=\"favicon.png\" rel=\"icon\" type=\"image/png\"/>\n\n  <title>example</title>\n  <link href=\"manifest.json\" rel=\"manifest\">\n</head>\n<body>\n<!-- This script installs service_worker.js to provide PWA functionality to\n     application. For more information, see:\n     https://developers.google.com/web/fundamentals/primers/service-workers -->\n<script>\n    var serviceWorkerVersion = null;\n    var scriptLoaded = false;\n    function loadMainDartJs() {\n      if (scriptLoaded) {\n        return;\n      }\n      scriptLoaded = true;\n      var scriptTag = document.createElement('script');\n      scriptTag.src = 'main.dart.js';\n      scriptTag.type = 'application/javascript';\n      document.body.append(scriptTag);\n    }\n\n    if ('serviceWorker' in navigator) {\n      // Service workers are supported. Use them.\n      window.addEventListener('load', function () {\n        // Wait for registration to finish before dropping the <script> tag.\n        // Otherwise, the browser will load the script multiple times,\n        // potentially different versions.\n        var serviceWorkerUrl = 'flutter_service_worker.js?v=' + serviceWorkerVersion;\n        navigator.serviceWorker.register(serviceWorkerUrl)\n          .then((reg) => {\n            function waitForActivation(serviceWorker) {\n              serviceWorker.addEventListener('statechange', () => {\n                if (serviceWorker.state == 'activated') {\n                  console.log('Installed new service worker.');\n                  loadMainDartJs();\n                }\n              });\n            }\n            if (!reg.active && (reg.installing || reg.waiting)) {\n              // No active web worker and we have installed or are installing\n              // one for the first time. Simply wait for it to activate.\n              waitForActivation(reg.installing || reg.waiting);\n            } else if (!reg.active.scriptURL.endsWith(serviceWorkerVersion)) {\n              // When the app updates the serviceWorkerVersion changes, so we\n              // need to ask the service worker to update.\n              console.log('New service worker available.');\n              reg.update();\n              waitForActivation(reg.installing);\n            } else {\n              // Existing service worker is still good.\n              console.log('Loading app from service worker.');\n              loadMainDartJs();\n            }\n          });\n\n        // If service worker doesn't succeed in a reasonable amount of time,\n        // fallback to plaint <script> tag.\n        setTimeout(() => {\n          if (!scriptLoaded) {\n            console.warn(\n              'Failed to load app from service worker. Falling back to plain <script> tag.',\n            );\n            loadMainDartJs();\n          }\n        }, 4000);\n      });\n    } else {\n      // Service workers not supported. Just drop the <script> tag.\n      loadMainDartJs();\n    }\n\n\n\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "example/web/manifest.json",
    "content": "{\n  \"name\": \"example\",\n  \"short_name\": \"example\",\n  \"start_url\": \".\",\n  \"display\": \"standalone\",\n  \"background_color\": \"#0175C2\",\n  \"theme_color\": \"#0175C2\",\n  \"description\": \"A new Flutter project.\",\n  \"orientation\": \"portrait-primary\",\n  \"prefer_related_applications\": false,\n  \"icons\": [\n    {\n      \"src\": \"icons/Icon-192.png\",\n      \"sizes\": \"192x192\",\n      \"type\": \"image/png\"\n    },\n    {\n      \"src\": \"icons/Icon-512.png\",\n      \"sizes\": \"512x512\",\n      \"type\": \"image/png\"\n    },\n    {\n      \"src\": \"icons/Icon-maskable-192.png\",\n      \"sizes\": \"192x192\",\n      \"type\": \"image/png\",\n      \"purpose\": \"maskable\"\n    },\n    {\n      \"src\": \"icons/Icon-maskable-512.png\",\n      \"sizes\": \"512x512\",\n      \"type\": \"image/png\",\n      \"purpose\": \"maskable\"\n    }\n  ]\n}\n"
  },
  {
    "path": "lib/flutter_settings_screens.dart",
    "content": "/// Settings Screen with Custom Storage Interface\n///\n/// Author: Harshvardhan Joshi\n///\n/// Based on the plugin by Barnabás BARTHA :\n///   https://github.com/BarthaBRW/shared_preferences_settings\nlibrary flutter_settings_screens;\n\nexport 'src/cache/cache.dart';\nexport 'src/settings.dart';\nexport 'src/utils/utils.dart';\nexport 'src/widgets/settings_widgets.dart';\n"
  },
  {
    "path": "lib/src/cache/cache.dart",
    "content": "export 'cache_provider.dart';\nexport 'cache_provider_impl.dart';\n"
  },
  {
    "path": "lib/src/cache/cache_provider.dart",
    "content": "import 'package:flutter_settings_screens/flutter_settings_screens.dart';\n\n/// This is an abstract class to provide access of storage/preferences platform\n/// from the developer's existing app to this settings screen\n///\n/// For example:\n///  the developer can choose to provide the existing preference platform\n///  access by providing the implementation for this class.\n///\n///  if the developer is using the `shared_preferences` library, then the implementation\n///  of one of the methods would look like this:\n///  ``` dart\n///        // SharedPreferences _preferences = await SharedPreferences.getInstance();\n///\n///         String? getString(String key, {String? defaultValue}) {\n///           return _preferences.getString(key) ?? defaultValue;\n///         }\n///\n///         Future<void> setBool(String key, bool? value) async {\n///           await _preferences.setBool(key, value);\n///         }\n///  ```\n///\n///  and if the developer is using the Hive library or storing preferences/data\n///  then the implementation would look like this:\n///\n///  ```dart\n///     //Box _preferences = await Hive.openBox(keyName);\n///       String? getString(String key,  {String? defaultValue}) {\n///         return _preferences.get(key) ?? defaultValue;\n///       }\n///\n///       Future<void> setBool(String key, bool? value) async {\n///         await _preferences.put(key, value);\n///       }\n///  ```\n///\n/// Similarly, if the developer is using any other type of library for this purpose,\n/// just providing the implementation using that library will be sufficient for\n/// using the settings screen\n///\n///\n/// For more details on how to properly implement this class, Check out the\n/// `cache_provider.dart` file in the example code of this library along with\n/// the existing [SharePreferenceCache] implementation.\n///\nabstract class CacheProvider {\n  CacheProvider();\n\n  /// Method to perform initializations regarding the underlying storage systems\n  /// ex. Creating instance of the SharedPreferences or Hive boxes\n  ///\n  /// This method must be called one the cache provider implementation to ensure\n  /// smooth operation.\n  Future<void> init();\n\n  /// Method to get Int value from the storage, if the retrieved value is null\n  /// then [defaultValue] should be used, if provided.\n  ///\n  ///\n  /// Example code(SharedPreferences Implementation):\n  /// ///  ```dart\n  ///       int? getInt(String key,  {int? defaultValue}) {\n  ///         return _preferences.getInt(key) ?? defaultValue;\n  ///       }\n  ///  ```\n  ///\n  /// The [defaultValue] is an optional & nullable value, you may choose not to provide it\n  /// in which case the null value will be returned as result.\n  ///\n  /// Output can be represented like this:\n  ///   getterOutput -if-absent-> defaultValue -if-absent-> null\n  ///\n  /// here [getterOutput] is the expected output of the getter method called.\n  /// The method must be implementation of one of the definitions from the cache provider\n  ///\n  int? getInt(String key, {int? defaultValue});\n\n  /// Method to get String value from the storage, if the retrieved value is null\n  /// then [defaultValue] should be used, if provided.\n  ///\n  ///\n  /// Example code(SharedPreferences Implementation):\n  /// ///  ```dart\n  ///       String? getString(String key,  {String? defaultValue}) {\n  ///         return _preferences.getString(key) ?? defaultValue;\n  ///       }\n  ///  ```\n  ///\n  /// The [defaultValue] is an optional & nullable value, you may choose not to provide it\n  /// in which case the null value will be returned as result.\n  ///\n  /// Output can be represented like this:\n  ///   getterOutput -if-absent-> defaultValue -if-absent-> null\n  ///\n  /// here [getterOutput] is the expected output of the getter method called.\n  /// The method must be implementation of one of the definitions from the cache provider\n  ///\n  String? getString(String key, {String? defaultValue});\n\n  /// Method to get double value from the storage, if the retrieved value is null\n  /// then [defaultValue] should be used, if provided.\n  ///\n  ///\n  /// Example code(SharedPreferences Implementation):\n  /// ///  ```dart\n  ///       double? getDouble(String key,  {double? defaultValue}) {\n  ///         return _preferences.getDouble(key) ?? defaultValue;\n  ///       }\n  ///  ```\n  ///\n  /// The [defaultValue] is an optional & nullable value, you may choose not to provide it\n  /// in which case the null value will be returned as result.\n  ///\n  /// Output can be represented like this:\n  ///   getterOutput -if-absent-> defaultValue -if-absent-> null\n  ///\n  /// here [getterOutput] is the expected output of the getter method called.\n  /// The method must be implementation of one of the definitions from the cache provider\n  ///\n  double? getDouble(String key, {double? defaultValue});\n\n  /// Method to get boolean value from the storage, if the retrieved value is null\n  /// then [defaultValue] should be used, if provided.\n  ///\n  ///\n  /// Example code(SharedPreferences Implementation):\n  /// ///  ```dart\n  ///       double? getBool(String key,  {bool? defaultValue}) {\n  ///         return _preferences.getBool(key) ?? defaultValue;\n  ///       }\n  ///  ```\n  ///\n  /// The [defaultValue] is an optional & nullable value, you may choose not to provide it\n  /// in which case the null value will be returned as result.\n  ///\n  /// Output can be represented like this:\n  ///   getterOutput -if-absent-> defaultValue -if-absent-> null\n  ///\n  /// here [getterOutput] is the expected output of the getter method called.\n  /// The method must be implementation of one of the definitions from the cache provider\n  ///\n  bool? getBool(String key, {bool? defaultValue});\n\n  /// Method to set int value to the storage, value can be null according\n  /// to the support by underlying storage system.\n  ///\n  ///\n  /// Example code(SharedPreferences Implementation):\n  /// ///  ```dart\n  ///       Future<void> getInt(String key, int? value) async {\n  ///         await _preferences.setInt(key, value);\n  ///       }\n  ///  ```\n  ///\n  Future<void> setInt(String key, int? value);\n\n  /// Method to set String value to the storage, value can be null according\n  /// to the support by underlying storage system.\n  ///\n  ///\n  /// Example code(SharedPreferences Implementation):\n  /// ///  ```dart\n  ///       Future<void> setString(String key, String? value) async {\n  ///         await _preferences.setString(key, value);\n  ///       }\n  ///  ```\n  ///\n  Future<void> setString(String key, String? value);\n\n  /// Method to set Double value to the storage, value can be null according\n  /// to the support by underlying storage system.\n  ///\n  ///\n  /// Example code(SharedPreferences Implementation):\n  /// ///  ```dart\n  ///       Future<void> setDouble(String key, double? value) async {\n  ///         await _preferences.setDouble(key, value);\n  ///       }\n  ///  ```\n  ///\n  Future<void> setDouble(String key, double? value);\n\n  /// Method to set boolean value to the storage, value can be null according\n  /// to the support by underlying storage system.\n  ///\n  ///\n  /// Example code(SharedPreferences Implementation):\n  /// ///  ```dart\n  ///       Future<void> setBool(String key, bool? value) async {\n  ///         await _preferences.setBool(key, value);\n  ///       }\n  ///  ```\n  ///\n  Future<void> setBool(String key, bool? value);\n\n  /// This method is used to check if a specific [key] is available/stored\n  /// in the underlying storage\n  bool containsKey(String key);\n\n  /// This method is used to get a set of available/stored keys\n  /// in the underlying storage.\n  ///\n  /// This method makes easy to iterate over stored keys for various\n  /// purposes.\n  ///\n  /// For example: finding a set of keys from all the available\n  /// keys that matches a regular expression\n  Set getKeys();\n\n  /// This method is used to remove provided [key] from the underlying storage system.\n  ///\n  /// For some storage systems, this call can be equivalent to setting null as\n  /// value for the given [key]\n  ///\n  Future<void> remove(String key);\n\n  /// This method is used to remove all the available/stored keys from the\n  /// underlying storage system.\n  ///\n  /// Implementing this method can utilize the [getKeys] method to iterate & remove\n  /// or can use interface methods with same purpose provided by the underlying\n  /// storage system\n  Future<void> removeAll();\n\n  /// Method to set custom object value to the storage, value can be null according\n  /// to the support by underlying storage system.\n  ///\n  /// Example code(SharedPreferences Implementation):\n  /// ///  ```dart\n  ///       Future<void> setObject<T>(String key, T? value) async {\n  ///        if (T is int || value is int) {\n  ///          await _preferences?.setInt(key, value as int);\n  ///        }\n  ///        if (T is double || value is double) {\n  ///          await _preferences?.setDouble(key, value as double);\n  ///        }\n  ///        if (T is bool || value is bool) {\n  ///          await _preferences?.setBool(key, value as bool);\n  ///        }\n  ///        if (T is String || value is String) {\n  ///          await _preferences?.setString(key, value as String);\n  ///        }\n  ///        throw Exception('No Implementation Found');\n  ///       }\n  ///  ```\n  ///\n  Future<void> setObject<T>(String key, T? value);\n\n  /// Method to get custom object value from the storage, if the retrieved value is null\n  /// then [defaultValue] should be used, if provided.\n  ///\n  ///\n  /// Example code(SharedPreferences Implementation):\n  /// ///  ```dart\n  ///       T? getValue<T>(String key,  {T? defaultValue}) {\n  ///             if (T is int || defaultValue is int) {\n  ///               return _preferences?.getInt(key) as T;\n  ///             }\n  ///             if (T is double || defaultValue is double) {\n  ///               return _preferences?.getDouble(key) as T;\n  ///             }\n  ///             if (T is bool || defaultValue is bool) {\n  ///               return _preferences?.getBool(key) as T;\n  ///             }\n  ///             if (T is String || defaultValue is String) {\n  ///               return _preferences?.getString(key) as T;\n  ///             }\n  ///             throw Exception('No Implementation Found');\n  ///       }\n  ///  ```\n  ///\n  /// T - Represents any valid class or primitive types supported by flutter\n  ///\n  /// The [defaultValue] is an optional & nullable value, you may choose not to provide it\n  /// in which case the null value will be returned as result.\n  ///\n  /// Output can be represented like this:\n  ///   getterOutput -if-absent-> defaultValue -if-absent-> null\n  ///\n  /// here [getterOutput] is the expected output of the getter method called.\n  /// The method must be implementation of one of the definitions from the cache provider\n  ///\n  T? getValue<T>(String key, {T? defaultValue});\n}\n"
  },
  {
    "path": "lib/src/cache/cache_provider_impl.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:shared_preferences/shared_preferences.dart';\n\nimport 'cache_provider.dart';\n\n/// A cache access provider class for shared preferences using shared_preferences library.\n///\n/// This cache provider implementation is used by default, if none is provided explicitly.\nclass SharePreferenceCache extends CacheProvider {\n  SharedPreferences? _preferences;\n\n  @override\n  Future<void> init() async {\n    WidgetsFlutterBinding.ensureInitialized();\n    _preferences = await SharedPreferences.getInstance();\n  }\n\n  Set get keys => getKeys();\n\n  @override\n  bool? getBool(String key, {bool? defaultValue}) {\n    return _preferences?.getBool(key);\n  }\n\n  @override\n  double? getDouble(String key, {double? defaultValue}) {\n    return _preferences?.getDouble(key);\n  }\n\n  @override\n  int? getInt(String key, {int? defaultValue}) {\n    return _preferences?.getInt(key);\n  }\n\n  @override\n  String? getString(String key, {String? defaultValue}) {\n    return _preferences?.getString(key);\n  }\n\n  @override\n  Future<void> setBool(String key, bool? value) async {\n    await _preferences?.setBool(key, value ?? false);\n  }\n\n  @override\n  Future<void> setDouble(String key, double? value) async {\n    await _preferences?.setDouble(key, value!);\n  }\n\n  @override\n  Future<void> setInt(String key, int? value) async {\n    await _preferences?.setInt(key, value!);\n  }\n\n  @override\n  Future<void> setString(String key, String? value) async {\n    await _preferences?.setString(key, value!);\n  }\n\n  @override\n  Future<void> setObject<T>(String key, T? value) async {\n    if (T == int || value is int) {\n      await _preferences?.setInt(key, value as int);\n    } else if (T == double || value is double) {\n      await _preferences?.setDouble(key, value as double);\n    } else if (T == bool || value is bool) {\n      await _preferences?.setBool(key, value as bool);\n    } else if (T == String || value is String) {\n      await _preferences?.setString(key, value as String);\n    } else {\n      throw Exception(\n          \"flutter_settings_screens doesn't handle values of type $T\");\n    }\n  }\n\n  @override\n  bool containsKey(String key) {\n    return _preferences?.containsKey(key) ?? false;\n  }\n\n  @override\n  Set getKeys() {\n    return _preferences?.getKeys() ?? {};\n  }\n\n  @override\n  Future<void> remove(String key) async {\n    if (containsKey(key)) {\n      await _preferences?.remove(key);\n    }\n  }\n\n  @override\n  Future<void> removeAll() async {\n    await _preferences?.clear();\n  }\n\n  @override\n  T? getValue<T>(String key, {T? defaultValue}) {\n    if (T == int || defaultValue is int) {\n      return _preferences?.getInt(key) as T;\n    }\n    if (T == double || defaultValue is double) {\n      return _preferences?.getDouble(key) as T;\n    }\n    if (T == bool || defaultValue is bool) {\n      return _preferences?.getBool(key) as T;\n    }\n    if (T == String || defaultValue is String) {\n      return _preferences?.getString(key) as T;\n    }\n    throw Exception(\n        \"flutter_settings_screens doesn't handle values of type $T\");\n  }\n}\n"
  },
  {
    "path": "lib/src/settings.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport 'cache/cache.dart';\n\n/// This function type is used for rebuilding any given child widgets\n///\n/// All Settings Tile are given a [ValueChangeObserver] with a unique settings key.\n///\n/// When the value associated with a settings key changes, [ValueChangeObserver]\n/// triggers a [InternalWidgetBuilder] function call.\ntypedef InternalWidgetBuilder<T> = Widget Function(\n    BuildContext, T, ValueChanged<T>);\n\n/// This function type is used for building a widget based on the value given to it.\n/// It is an alternate version of [WidgetBuilder].\ntypedef ItemBuilder<T> = Widget Function(T);\n\n/// This function type is used for triggering the callback when value\n/// associated with a settings key changes.\ntypedef OnChanged<T> = void Function(T);\n\n/// This function type is used for verifying that the dialog/modal\n/// widget is to be closed or not.\n///\n/// if true, the widget will be closed\ntypedef OnConfirmedCallback = bool Function();\n\n/// This class behaves as a bridge between the settings screen widgets and the\n/// underlying storage mechanism.\n///\n/// To access the storage mechanism an instance of the [CacheProvider] implementation\n/// is required.\n///\n/// Any Flutter App using this library must call `Settings.init(cacheProvider)`\n/// before showing the settings screen.\n///\n///\nclass Settings {\n  /// Private constructor\n  Settings._internal();\n\n  /// Private instance of this class to keep it singleton\n  static final Settings _instance = Settings._internal();\n\n  /// Public factory method to provide the\n  factory Settings() {\n    assert(\n        _cacheProvider != null,\n        'Must call Settings.init(cacheProvider)'\n        ' before using settings!');\n    return _instance;\n  }\n\n  /// Private instance of [CacheProvider] which will allow access to the\n  /// underlying cache mechanism, which can be any of [SharedPreference],[Hive]\n  /// or any other cache provider of choice\n  static CacheProvider? _cacheProvider;\n\n  /// This method will check and ensure that [_cacheProvider]\n  /// value is set properly.\n  static void ensureCacheProvider() {\n    assert(\n        isInitialized,\n        'Must call Settings.init(cacheProvider)'\n        ' before using settings!');\n  }\n\n  /// A getter to know if the settings are already initialized or not\n  static bool get isInitialized => _cacheProvider != null;\n\n  /// This method is used for initializing the [_cacheProvider]\n  /// instance.\n  ///\n  /// This method must be called before the Settings screen is displayed.\n  ///\n  /// Cache provider is optional, default cache provider uses the\n  /// shared preferences based cache provider implementation.\n  static Future<void> init({CacheProvider? cacheProvider}) async {\n    cacheProvider ??= SharePreferenceCache();\n\n    _cacheProvider = cacheProvider;\n    await _cacheProvider!.init();\n  }\n\n  /// method to check if the cache provider contains given [key] or not.\n  static bool? containsKey(String key) {\n    ensureCacheProvider();\n    return _cacheProvider?.containsKey(key);\n  }\n\n  /// method to get a value using the [cacheProvider] for given [key]\n  ///\n  /// If there's no value found associated with the [key] then the [defaultValue]\n  /// is returned.\n  static T? getValue<T>(String key, {T? defaultValue}) {\n    ensureCacheProvider();\n    final containsKey = _cacheProvider?.containsKey(key);\n    if (containsKey ?? false) {\n      final prefValue =\n          _cacheProvider?.getValue<T>(key, defaultValue: defaultValue);\n      return prefValue ?? defaultValue;\n    }\n    return defaultValue;\n  }\n\n  /// method to set [value] using the [cacheProvider] for given [key]\n  static Future<void> setValue<T>(\n    String key,\n    T value, {\n    bool notify = false,\n  }) async {\n    ensureCacheProvider();\n    if (value == null) {\n      return _cacheProvider?.remove(key);\n    }\n    await _cacheProvider?.setObject<T>(key, value);\n    if (notify) {\n      _notifyGlobally<T>(key, value);\n    }\n  }\n\n  /// method to clear all the cached data using the [cacheProvider]\n  static void clearCache() {\n    ensureCacheProvider();\n    _cacheProvider?.removeAll();\n  }\n}\n\n/// This class is a customized version of [ValueNotifier]\n/// which Takes a [key] and [value].\n///\n/// Value - Setting value which is associated to the [key]\nclass ValueChangeNotifier<T> extends ValueNotifier<T> {\n  /// A String which represents a setting (assumed to be unique)\n  final String key;\n\n  ValueChangeNotifier(this.key, value) : super(value);\n\n  @override\n  set value(T newValue) {\n    Settings.setValue<T>(key, newValue);\n    super.value = newValue;\n    _notifyGlobally(key, newValue);\n  }\n\n  @override\n  void notifyListeners() {\n    super.notifyListeners();\n  }\n\n  @override\n  String toString() {\n    return '\\n{VCN: \\n\\tkey: $key  \\n\\tvalue: $value\\n}';\n  }\n}\n\nvoid _notifyGlobally<T>(String key, T newValue) {\n  final notifiers = _fetchNotifiersForKey(key);\n  if (notifiers == null || notifiers.isEmpty) return;\n\n  for (var notifier in notifiers) {\n    final currentValue = notifier.value;\n    if (currentValue != newValue) {\n      notifier.value = newValue;\n      // ignore: avoid_print\n      print(': _notifyGlobally: updating $key notifier');\n    }\n  }\n}\n\nList<ValueChangeNotifier>? _fetchNotifiersForKey<T>(String key) {\n  final finalKey = key.toLowerCase().trim();\n  return _notifiers[finalKey];\n}\n\n/// This map is used for keeping the track of the notifier(s) associated with\n/// a Settings key\n///\n/// If a settings key is already added in the map, the new notifier\n/// is added to the list of notifiers\nMap<String, List<ValueChangeNotifier>> _notifiers =\n    <String, List<ValueChangeNotifier>>{};\n\n/// A Stateful widget which Takes in a [cacheKey], a [defaultValue]\n/// and a [builder]\n///\n/// This widget rebuilds whenever there's a change in value associated with the\n/// [cacheKey]\nclass ValueChangeObserver<T> extends StatefulWidget {\n  final String cacheKey;\n  final T defaultValue;\n  final InternalWidgetBuilder<T> builder;\n\n  const ValueChangeObserver({\n    super.key,\n    required this.cacheKey,\n    required this.defaultValue,\n    required this.builder,\n  });\n\n  @override\n  State<ValueChangeObserver<T>> createState() => _ValueChangeObserverState<T>();\n}\n\nclass _ValueChangeObserverState<T> extends State<ValueChangeObserver<T>> {\n  T? value;\n\n  String get cacheKey => widget.cacheKey;\n\n  T get defaultValue => widget.defaultValue;\n\n  late ValueChangeNotifier<T> notifier;\n\n  @override\n  void dispose() {\n    if (!mounted) {\n      _notifiers.remove(cacheKey);\n    }\n    super.dispose();\n  }\n\n  @override\n  void initState() {\n    //if [cacheKey] is not found, add new cache in the [cacheProvider] with [defaultValue]\n    final containsKey = Settings.containsKey(cacheKey) ?? false;\n    if (!containsKey) {\n      Settings.setValue<T>(cacheKey, defaultValue);\n    }\n\n    // get cache value from the [cacheProvider]\n    value = Settings.getValue<T>(cacheKey, defaultValue: defaultValue);\n\n    // assign a notifier\n    notifier = ValueChangeNotifier<T>(cacheKey, value);\n\n    // add notifier to [_notifiers] map\n    if (!_notifiers.containsKey(cacheKey)) {\n      _notifiers[cacheKey] = List<ValueChangeNotifier<T>>.empty(growable: true);\n    }\n    _notifiers[cacheKey]?.add(notifier);\n    super.initState();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return ValueListenableBuilder<T>(\n      valueListenable: notifier,\n      builder: (BuildContext context, T value, Widget? child) {\n        return widget.builder(context, value, onChange);\n      },\n    );\n  }\n\n  /// This method is used to trigger all the associated notifiers\n  /// when associated value is changed in cache\n  void onChange(T newValue) {\n    _notifiers[cacheKey]?.forEach((notifier) {\n      notifier.value = newValue;\n    });\n  }\n}\n"
  },
  {
    "path": "lib/src/utils/utils.dart",
    "content": "import 'dart:ui';\n\nclass ConversionUtils {\n  static Color colorFromString(String colorString) {\n    colorString = colorString.replaceFirst('#', '');\n    colorString = colorString.length == 6 ? 'ff$colorString' : colorString;\n    final colorHexInt = int.parse(colorString, radix: 16);\n    return Color(colorHexInt);\n  }\n\n  static int intFromString(String value) {\n    const alphaString = 'ff000000';\n    return int.parse(value, radix: 16) & int.parse(alphaString, radix: 16);\n  }\n\n  static String stringFromColor(Color color) {\n    return '#${color.value.toRadixString(16)}';\n  }\n}\n"
  },
  {
    "path": "lib/src/utils/widget_utils.dart",
    "content": "import 'package:flutter/material.dart';\n\n/// A method that will add default leading padding to all children in the list\nList<Widget> getPaddedParentChildrenList(List<Widget> childrenIfEnabled) {\n  return childrenIfEnabled.map<Widget>((childWidget) {\n    return Padding(\n      padding: const EdgeInsets.only(left: 8.0),\n      child: childWidget,\n    );\n  }).toList();\n}\n\nTextStyle? headerTextStyle(BuildContext context) =>\n    Theme.of(context).textTheme.titleLarge?.copyWith(fontSize: 16.0);\n\nTextStyle? subtitleTextStyle(BuildContext context) => Theme.of(context)\n    .textTheme\n    .titleSmall\n    ?.copyWith(fontSize: 13.0, fontWeight: FontWeight.normal);\n"
  },
  {
    "path": "lib/src/widgets/base_widgets.dart",
    "content": "part of 'settings_widgets.dart';\n\n/// [SettingsScreen] is a simple Screen widget that may contain Tiles or other\n/// widgets.\n///\n/// * Example:\n/// ```dart\n/// SettingsScreen(\n///   title: 'Application Settings',\n///   children: <Widget>[\n///     SettingsGroup(\n///            title: 'Single Choice Settings',\n///            children: <Widget>[\n///              SwitchSettingsTile(\n///                settingKey: 'key-wifi',\n///                title: 'Wi-Fi',\n///                enabledLabel: 'Enabled',\n///                disabledLabel: 'Disabled',\n///                leading: Icon(Icons.wifi),\n///                onChange: (value) {\n///                  debugPrint('key-wifi: $value');\n///                },\n///              ),\n///              CheckboxSettingsTile(\n///                settingKey: 'key-blue-tooth',\n///                title: 'Bluetooth',\n///                enabledLabel: 'Enabled',\n///                disabledLabel: 'Disabled',\n///                leading: Icon(Icons.bluetooth),\n///                onChange: (value) {\n///                  debugPrint('key-blue-tooth: $value');\n///                },\n///              ),\n///              SwitchSettingsTile(\n///                leading: Icon(Icons.developer_mode),\n///                settingKey: 'key-switch-dev-mode',\n///                title: 'Developer Settings',\n///                onChange: (value) {\n///                  debugPrint('key-switch-dev-mod: $value');\n///                },\n///                childrenIfEnabled: <Widget>[\n///                  CheckboxSettingsTile(\n///                    leading: Icon(Icons.adb),\n///                    settingKey: 'key-is-developer',\n///                    title: 'Developer Mode',\n///                    onChange: (value) {\n///                      debugPrint('key-is-developer: $value');\n///                    },\n///                  ),\n///                  SwitchSettingsTile(\n///                    leading: Icon(Icons.usb),\n///                    settingKey: 'key-is-usb-debugging',\n///                    title: 'USB Debugging',\n///                    onChange: (value) {\n///                      debugPrint('key-is-usb-debugging: $value');\n///                    },\n///                  ),\n///                  SimpleSettingsTile(\n///                    title: 'Root Settings',\n///                    subtitle: 'These settings is not accessible',\n///                    enabled: false,\n///                  ),\n///               ],\n///             ),\n///          ],\n///       ),\n///   ],\n/// );\n/// ```\nclass SettingsScreen extends StatelessWidget {\n  /// Appbar title in Scaffold.\n  final String title;\n\n  /// Content of the screen, body of the Scaffold.\n  final List<Widget> children;\n\n  final bool hasAppBar;\n\n  const SettingsScreen({\n    super.key,\n    required this.children,\n    this.hasAppBar = true,\n    this.title = 'Settings',\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: hasAppBar\n          ? AppBar(\n              title: Text(title),\n            )\n          : null,\n      body: ListView.builder(\n        shrinkWrap: true,\n        itemCount: children.length,\n        itemBuilder: (BuildContext context, int index) {\n          return children[index];\n        },\n      ),\n    );\n  }\n}\n\n/// [_SettingsTile] is a Basic Building block for Any Settings widget.\n///\n/// This widget is container for any widget which is to be used for setting.\nclass _SettingsTile extends StatefulWidget {\n  /// title string for the tile\n  final String title;\n\n  /// widget to be placed at first in the tile\n  final Widget? leading;\n\n  /// subtitle string for the tile\n  final String? subtitle;\n\n  /// title text style\n  final TextStyle? titleTextStyle;\n\n  /// subtitle text style\n  final TextStyle? subtitleTextStyle;\n\n  /// flag to represent if the tile is accessible or not, if false user input is ignored\n  final bool enabled;\n\n  /// widget which is placed as the main element of the tile as settings UI\n  final Widget child;\n\n  /// call back for handling the tap event on tile\n  final GestureTapCallback? onTap;\n\n  // /// flag to show the child below the main tile elements\n  // final bool showChildBelow;\n\n  final bool showDivider;\n\n  const _SettingsTile({\n    required this.title,\n    required this.child,\n    this.subtitle = '',\n    this.titleTextStyle,\n    this.subtitleTextStyle,\n    this.onTap,\n    this.enabled = true,\n    // this.showChildBelow = false,\n    this.leading,\n    this.showDivider = true,\n  });\n\n  @override\n  __SettingsTileState createState() => __SettingsTileState();\n}\n\nclass __SettingsTileState extends State<_SettingsTile> {\n  @override\n  void initState() {\n    super.initState();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Material(\n      child: Column(\n        crossAxisAlignment: CrossAxisAlignment.stretch,\n        children: <Widget>[\n          ListTile(\n            leading: widget.leading,\n            title: Text(\n              widget.title,\n              style: widget.titleTextStyle ?? headerTextStyle(context),\n            ),\n            subtitle: widget.subtitle?.isEmpty ?? true\n                ? null\n                : Text(\n                    widget.subtitle!,\n                    style:\n                        widget.subtitleTextStyle ?? subtitleTextStyle(context),\n                  ),\n            enabled: widget.enabled,\n            onTap: widget.onTap,\n            // trailing: Visibility(\n            //   visible: !widget.showChildBelow,\n            //   child: widget.child,\n            // ),\n            trailing: widget.child,\n            dense: true,\n            // wrap only if the subtitle is longer than 70 characters\n            isThreeLine: (widget.subtitle?.isNotEmpty ?? false) &&\n                widget.subtitle!.length > 70,\n          ),\n          // Visibility(\n          //   visible: widget.showChildBelow,\n          //   child: widget.child,\n          // ),\n          if (widget.showDivider) _SettingsTileDivider(),\n        ],\n      ),\n    );\n  }\n}\n\n/// [_SimpleHeaderTile] is a widget which is used to show Leading, Title and subtitle\n/// of a [_SettingsTile] without the main child widget\nclass _SimpleHeaderTile extends StatefulWidget {\n  /// title string for the tile\n  final String? title;\n\n  /// subtitle string for the tile\n  final String? subtitle;\n\n  /// title text style\n  final TextStyle? titleTextStyle;\n\n  /// subtitle text style\n  final TextStyle? subtitleTextStyle;\n\n  /// widget to be placed at first in the tile\n  final Widget? leading;\n\n  const _SimpleHeaderTile({\n    this.title,\n    this.subtitle = '',\n    this.leading,\n    this.titleTextStyle,\n    this.subtitleTextStyle,\n  });\n\n  @override\n  __SimpleHeaderTileState createState() => __SimpleHeaderTileState();\n}\n\nclass __SimpleHeaderTileState extends State<_SimpleHeaderTile> {\n  @override\n  Widget build(BuildContext context) {\n    return AbsorbPointer(\n      child: ListTile(\n        title: Text(\n          widget.title ?? '',\n          style: widget.titleTextStyle ?? headerTextStyle(context),\n        ),\n        subtitle: (widget.subtitle?.isNotEmpty ?? false)\n            ? Text(\n                widget.subtitle!,\n                style: widget.subtitleTextStyle ?? subtitleTextStyle(context),\n              )\n            : null,\n        leading: widget.leading,\n      ),\n    );\n  }\n}\n\n/// [_ExpansionSettingsTile] is a special setting widget which has two states.\n///\n/// Collapsed State:\n///   In this state the settings tile would only show the Title,Subtitle and leading\n///   widget\n///\n/// Expanded State:\n///   In this state the settings tile would show all widgets in collapsed state,\n///   but also the children widgets.\nclass _ExpansionSettingsTile extends StatefulWidget {\n  /// title string for the tile\n  final String title;\n\n  /// subtitle string for the tile, default = ''\n  final String subtitle;\n\n  /// title text style\n  final TextStyle? titleTextStyle;\n\n  /// subtitle text style\n  final TextStyle? subtitleTextStyle;\n\n  /// flag to represent if the tile is accessible or not, if false user input is ignored\n  /// default = true\n  final bool enabled;\n\n  /// flag to represent the current state of the expansion tile, if true it means that\n  /// the tile is in expanded mode\n  /// default = false\n  final bool expanded;\n\n  /// The widget displayed when the tile is expanded\n  final Widget child;\n\n  /// The widget shown in front of the title\n  final Widget? leading;\n\n  /// A Callback for the change of the Expansion state\n  final Function(bool)? onExpansionChanged;\n\n  final bool showDivider;\n\n  const _ExpansionSettingsTile({\n    required this.title,\n    required this.child,\n    this.subtitle = '',\n    this.titleTextStyle,\n    this.subtitleTextStyle,\n    this.enabled = true,\n    this.expanded = false,\n    this.onExpansionChanged,\n    this.leading,\n    this.showDivider = true,\n  });\n\n  @override\n  _ExpansionSettingsTileState createState() => _ExpansionSettingsTileState();\n}\n\nclass _ExpansionSettingsTileState extends State<_ExpansionSettingsTile> {\n  @override\n  void initState() {\n    super.initState();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return widget.enabled ? getExpansionTile() : getListTile();\n  }\n\n  Widget getListTile() {\n    return _SettingsTile(\n      title: widget.title,\n      subtitle: widget.subtitle,\n      enabled: false,\n      leading: widget.leading,\n      showDivider: widget.showDivider,\n      child: const Text(''),\n    );\n  }\n\n  Widget getExpansionTile() {\n    return Material(\n      child: ExpansionTile(\n        title: Text(\n          widget.title,\n          style: widget.titleTextStyle ?? headerTextStyle(context),\n        ),\n        leading: widget.leading,\n        subtitle: Text(\n          widget.subtitle,\n          style: widget.subtitleTextStyle ?? subtitleTextStyle(context),\n        ),\n        initiallyExpanded: widget.expanded,\n        childrenPadding: const EdgeInsets.only(left: 8.0),\n        children: <Widget>[widget.child],\n      ),\n    );\n  }\n}\n\n///[_ModalSettingsTile] is a widget which shows the given child widget inside a\n/// dialog view.\n///\n/// This widget can be used to show a settings UI which is too big for a single\n///  tile in the SettingScreen UI or a Setting tile which needs to be shown separately.\nclass _ModalSettingsTile<T> extends StatefulWidget {\n  /// title string for the tile\n  final String title;\n\n  /// subtitle string for the tile, default = ''\n  final String? subtitle;\n\n  /// title text style\n  final TextStyle? titleTextStyle;\n\n  /// subtitle text style\n  final TextStyle? subtitleTextStyle;\n\n  /// flag to represent if the tile is accessible or not, if false user input is ignored\n  /// default = true\n  final bool enabled;\n\n  /// The widget shown in front of the title\n  final Widget? leading;\n\n  /// The list widgets which will be displayed in a vertical list manner\n  /// when the dialog is displayed\n  final List<Widget> children;\n\n  /// flag that determines if the dialog will be displayed with\n  /// confirmation buttons or not .\n  /// Buttons like, ok & cancel\n  ///\n  /// default = false\n  final bool showConfirmation;\n\n  /// Callback to execute when user taps cancel button,\n  /// It is a simple void callback to execute when user wants to revert the changes\n  /// back to previous\n  ///\n  /// **Note**: the action performed will not affect the settings that were updated\n  /// automatically. However you can choose to modify them as per your need by referencing\n  /// the values from the callback & updating\n  final VoidCallback? onCancel;\n\n  /// Callback to execute when user taps ok button, while [onCancel] callback\n  /// is a simple void callback, this one allows you to perform some task\n  /// before closing the dialog.\n  ///\n  /// **Note**: the action performed will not affect the settings that were updated\n  /// automatically. However you can choose to modify them as per your need by referencing\n  /// the values from the callback & updating\n  final OnConfirmedCallback? onConfirm;\n\n  const _ModalSettingsTile({\n    required this.title,\n    required this.children,\n    this.subtitle = '',\n    this.enabled = true,\n    this.leading,\n    this.showConfirmation = false,\n    this.onCancel,\n    this.onConfirm,\n    this.titleTextStyle,\n    this.subtitleTextStyle,\n  });\n\n  @override\n  __ModalSettingsTileState createState() => __ModalSettingsTileState();\n}\n\nclass __ModalSettingsTileState extends State<_ModalSettingsTile> {\n  @override\n  void initState() {\n    super.initState();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Material(\n      child: ListTile(\n        leading: widget.leading,\n        title: Text(widget.title,\n            style: widget.titleTextStyle ?? headerTextStyle(context)),\n        subtitle: Text(\n          widget.subtitle!,\n          style: widget.subtitleTextStyle ?? subtitleTextStyle(context),\n        ),\n        enabled: widget.enabled,\n        onTap: () => _showWidget(context, widget.children),\n        dense: true,\n      ),\n    );\n  }\n\n  void _showWidget(BuildContext context, List<Widget> children) {\n    showDialog(\n        context: context,\n        builder: (dialogContext) {\n          return SimpleDialog(\n            title: Center(\n              child: getTitle(),\n            ),\n            titlePadding: const EdgeInsets.fromLTRB(8.0, 10.0, 8.0, 10.0),\n            contentPadding: EdgeInsets.zero,\n            children: _finalWidgets(dialogContext, children),\n          );\n        });\n  }\n\n  List<Widget> _finalWidgets(\n      BuildContext dialogContext, List<Widget> children) {\n    if (!widget.showConfirmation) {\n      return children;\n    }\n    return _addActionWidgets(dialogContext, children);\n  }\n\n  Widget getTitle() {\n    return widget.leading != null\n        ? Row(\n            children: <Widget>[\n              widget.leading!,\n              Text(widget.title, style: headerTextStyle(context)),\n            ],\n          )\n        : Text(widget.title, style: headerTextStyle(context));\n  }\n\n  List<Widget> _addActionWidgets(\n      BuildContext dialogContext, List<Widget> children) {\n    final finalList = List<Widget>.from(children);\n    finalList.add(ButtonBar(\n      alignment: MainAxisAlignment.end,\n      children: <Widget>[\n        TextButton(\n          style: TextButton.styleFrom(\n            padding: EdgeInsets.zero,\n          ),\n          onPressed: () {\n            widget.onCancel?.call();\n            _disposeDialog(dialogContext);\n          },\n          child:\n              Text(MaterialLocalizations.of(dialogContext).cancelButtonLabel),\n        ),\n        TextButton(\n          style: TextButton.styleFrom(\n            padding: EdgeInsets.zero,\n          ),\n          onPressed: () async {\n            var closeDialog = true;\n            if (widget.onConfirm != null) {\n              closeDialog = widget.onConfirm!.call();\n            }\n\n            if (closeDialog) {\n              _disposeDialog(dialogContext);\n            }\n          },\n          child: Text(MaterialLocalizations.of(dialogContext).okButtonLabel),\n        )\n      ],\n    ));\n    return finalList;\n  }\n\n  void _disposeDialog(BuildContext dialogContext) {\n    Navigator.of(dialogContext).pop();\n  }\n}\n\n/// [_SettingsTileDivider] is widget which is used as a Divide various settings\n/// tile in a list\nclass _SettingsTileDivider extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return const Divider(\n      height: 0.0,\n    );\n  }\n}\n\n/// [_SettingsCheckbox] is a Settings UI version of the [Checkbox] widget.\nclass _SettingsCheckbox extends StatelessWidget {\n  /// current state of the checkbox\n  final bool value;\n\n  /// on change callback to handle state change\n  final OnChanged<bool?> onChanged;\n\n  /// flag which represents the state of the settings, if false the the tile will\n  /// ignore all the user inputs\n  final bool enabled;\n\n  const _SettingsCheckbox({\n    required this.value,\n    required this.onChanged,\n    required this.enabled,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return Checkbox(\n      value: value,\n      onChanged: enabled ? onChanged : null,\n      activeColor: Theme.of(context).colorScheme.secondary,\n    );\n  }\n}\n\n/// [_SettingsSwitch] is a Settings UI version of the [Switch] widget\nclass _SettingsSwitch extends StatelessWidget {\n  /// current state of the switch\n  final bool value;\n\n  /// on change callback to handle state change\n  final OnChanged<bool?> onChanged;\n\n  /// flag which represents the state of the settings, if false the the tile will\n  /// ignore all the user inputs\n  final bool enabled;\n\n  final Color? activeColor;\n\n  const _SettingsSwitch({\n    required this.value,\n    required this.onChanged,\n    required this.enabled,\n    required this.activeColor,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return Switch.adaptive(\n      value: value,\n      onChanged: enabled ? onChanged : null,\n      activeColor: activeColor ?? Theme.of(context).colorScheme.secondary,\n    );\n  }\n}\n\n/// [_SettingsRadio] is a Settings UI version of the [Radio] widgets\nclass _SettingsRadio<T> extends StatelessWidget {\n  /// value of the selected radio in this group\n  final T groupValue;\n\n  /// value of the current radio widget\n  final T value;\n\n  /// on change callback to handle state change\n  final OnChanged<T?> onChanged;\n\n  /// flag which represents the state of the settings, if false the the tile will\n  /// ignore all the user inputs\n  final bool enabled;\n\n  final Color? activeColor;\n\n  const _SettingsRadio({\n    required this.groupValue,\n    required this.value,\n    required this.onChanged,\n    required this.enabled,\n    required this.activeColor,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return Radio<T>(\n      groupValue: groupValue,\n      value: value,\n      onChanged: enabled ? onChanged : null,\n      activeColor: activeColor,\n    );\n  }\n}\n\n/// [_SettingsDropDown] is a Settings UI version of the [DropdownButton]\nclass _SettingsDropDown<T> extends StatelessWidget {\n  /// value of the selected in this dropdown\n  final T selected;\n\n  /// Alignment of the dropdown. Defaults to [AlignmentDirectional.centerEnd].\n  final AlignmentGeometry alignment;\n\n  /// List of values for this dropdown\n  final List<T> values;\n\n  /// on change call back to handle selected value change\n  final OnChanged<T?> onChanged;\n\n  /// single item builder for creating a [DropdownMenuItem]\n  final ItemBuilder<T> itemBuilder;\n\n  /// flag which represents the state of the settings, if false the the tile will\n  /// ignore all the user inputs\n  final bool enabled;\n\n  const _SettingsDropDown({\n    required this.selected,\n    required this.values,\n    required this.onChanged,\n    required this.itemBuilder,\n    this.alignment = AlignmentDirectional.centerEnd,\n    this.enabled = true,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return Wrap(\n      alignment: WrapAlignment.end,\n      children: <Widget>[\n        DropdownButton<T>(\n          isDense: true,\n          value: selected,\n          alignment: alignment,\n          onChanged: enabled ? onChanged : null,\n          underline: Container(),\n          items: values.map<DropdownMenuItem<T>>(\n            (T val) {\n              return DropdownMenuItem<T>(\n                value: val,\n                child: itemBuilder(val),\n              );\n            },\n          ).toList(),\n        ),\n      ],\n    );\n  }\n}\n\n/// [_SettingsSlider] is a Settings UI version of [Slider] widget\nclass _SettingsSlider extends StatelessWidget {\n  /// min value allowed for the slider\n  final double min;\n\n  /// max value allowed for the slider\n  final double max;\n\n  /// step value for slider interval\n  final double step;\n\n  /// current value of the slider\n  final double value;\n\n  /// on change callback to handle the value change when slider starts moving\n  final OnChanged<double>? onChangeStart;\n\n  /// on change callback to handle the value change\n  final OnChanged<double>? onChanged;\n\n  /// on change callback to handle the value change when slider stops moving\n  final OnChanged<double>? onChangeEnd;\n\n  /// flag which represents the state of the settings, if false then the tile will\n  /// ignore all the user inputs\n  final bool enabled;\n\n  /// flag which allows updating the value of setting immediately when the\n  /// slider is moved, default = true\n  ///\n  /// If this flag is enabled then [onChangeStart] & [onChangeEnd] callbacks are\n  /// ignored & will not be executed\n  final bool eagerUpdate;\n\n  final Color? activeColor;\n  final Color? inActiveColor;\n\n  const _SettingsSlider({\n    required this.value,\n    required this.min,\n    required this.max,\n    required this.step,\n    required this.enabled,\n    required this.activeColor,\n    required this.inActiveColor,\n    this.onChangeStart,\n    this.onChanged,\n    this.onChangeEnd,\n    this.eagerUpdate = true,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return Slider.adaptive(\n      value: value,\n      min: min,\n      max: max,\n      divisions: (max - min) ~/ (step),\n      onChangeStart: enabled && !eagerUpdate\n          ? (value) => onChangeStart?.call(value)\n          : null,\n      onChanged: enabled ? (value) => onChanged?.call(value) : null,\n      onChangeEnd:\n          enabled && !eagerUpdate ? (value) => onChangeEnd?.call(value) : null,\n      activeColor: activeColor,\n      inactiveColor: inActiveColor,\n    );\n  }\n}\n\n/// [_SettingsColorPicker] is a widget which allows picking colors\n/// from pallet of colors\nclass _SettingsColorPicker extends StatelessWidget {\n  /// title of the settings tile and color pallet dialog\n  final String title;\n\n  final String subtitle;\n\n  /// title text style\n  final TextStyle? titleTextStyle;\n\n  /// subtitle text style\n  final TextStyle? subtitleTextStyle;\n\n  /// The widget shown in front of the title\n  final Widget? leading;\n\n  /// current value of the slider\n  final String value;\n\n  /// on change callback to handle the value change\n  final OnChanged<String> onChanged;\n\n  /// flag which represents the state of the settings, if false the the tile will\n  /// ignore all the user inputs\n  final bool enabled;\n\n  final bool showDivider;\n\n  const _SettingsColorPicker({\n    required this.value,\n    required this.onChanged,\n    required this.enabled,\n    required this.title,\n    this.subtitle = '',\n    this.leading,\n    this.titleTextStyle,\n    this.subtitleTextStyle,\n    this.showDivider = true,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return _SettingsTile(\n      title: title,\n      subtitle: subtitle.isNotEmpty ? subtitle : value,\n      leading: leading,\n      enabled: enabled,\n      onTap: () => _showColorPicker(context, value),\n      titleTextStyle: titleTextStyle,\n      subtitleTextStyle: subtitleTextStyle,\n      showDivider: showDivider,\n      child: FloatingActionButton(\n        heroTag: null,\n        backgroundColor: ConversionUtils.colorFromString(value),\n        elevation: 0,\n        onPressed: enabled ? () => _showColorPicker(context, value) : null,\n      ),\n    );\n  }\n\n  void _showColorPicker(BuildContext context, String value) {\n    Widget dialogContent = MaterialColorPicker(\n      shrinkWrap: true,\n      selectedColor: ConversionUtils.colorFromString(value),\n      onColorChange: (Color? color) {\n        if (color == null) return;\n        onChanged(ConversionUtils.stringFromColor(color));\n      },\n    );\n\n    showDialog(\n      context: context,\n      builder: (dialogContext) {\n        return AlertDialog(\n          title: const Text('Pick a Color'),\n          content: dialogContent,\n        );\n      },\n    );\n  }\n}\n"
  },
  {
    "path": "lib/src/widgets/color_picker/circle_color.dart",
    "content": "import 'package:flutter/material.dart';\n\nclass CircleColor extends StatelessWidget {\n  static const double _kColorElevation = 4.0;\n\n  final bool isSelected;\n  final Color color;\n  final VoidCallback? onColorChoose;\n  final double circleSize;\n  final double? elevation;\n  final IconData? iconSelected;\n\n  const CircleColor({\n    super.key,\n    required this.color,\n    required this.circleSize,\n    this.onColorChoose,\n    this.isSelected = false,\n    this.elevation = _kColorElevation,\n    this.iconSelected,\n  }) : assert(!isSelected || (isSelected && iconSelected != null));\n\n  @override\n  Widget build(BuildContext context) {\n    final brightness = ThemeData.estimateBrightnessForColor(color);\n    final icon = brightness == Brightness.light ? Colors.black : Colors.white;\n\n    return GestureDetector(\n      onTap: onColorChoose,\n      child: Material(\n        elevation: elevation ?? _kColorElevation,\n        shape: const CircleBorder(),\n        child: CircleAvatar(\n          radius: circleSize / 2,\n          backgroundColor: color,\n          child: isSelected ? Icon(iconSelected, color: icon) : null,\n        ),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/src/widgets/color_picker/colors.dart",
    "content": "import 'package:flutter/material.dart';\n\nconst List<ColorSwatch> materialColors = <ColorSwatch>[\n  Colors.red,\n  Colors.pink,\n  Colors.purple,\n  Colors.deepPurple,\n  Colors.indigo,\n  Colors.blue,\n  Colors.lightBlue,\n  Colors.cyan,\n  Colors.teal,\n  Colors.green,\n  Colors.lightGreen,\n  Colors.lime,\n  Colors.yellow,\n  Colors.amber,\n  Colors.orange,\n  Colors.deepOrange,\n  Colors.brown,\n  Colors.grey,\n  Colors.blueGrey\n];\n\nconst List<ColorSwatch> accentColors = <ColorSwatch>[\n  Colors.redAccent,\n  Colors.pinkAccent,\n  Colors.purpleAccent,\n  Colors.deepPurpleAccent,\n  Colors.indigoAccent,\n  Colors.blueAccent,\n  Colors.lightBlueAccent,\n  Colors.cyanAccent,\n  Colors.tealAccent,\n  Colors.greenAccent,\n  Colors.lightGreenAccent,\n  Colors.limeAccent,\n  Colors.yellowAccent,\n  Colors.amberAccent,\n  Colors.orangeAccent,\n  Colors.deepOrangeAccent,\n];\n\nconst List<ColorSwatch> fullMaterialColors = <ColorSwatch>[\n  ColorSwatch(0xFFFFFFFF, {500: Colors.white}),\n  ColorSwatch(0xFF000000, {500: Colors.black}),\n  Colors.red,\n  Colors.redAccent,\n  Colors.pink,\n  Colors.pinkAccent,\n  Colors.purple,\n  Colors.purpleAccent,\n  Colors.deepPurple,\n  Colors.deepPurpleAccent,\n  Colors.indigo,\n  Colors.indigoAccent,\n  Colors.blue,\n  Colors.blueAccent,\n  Colors.lightBlue,\n  Colors.lightBlueAccent,\n  Colors.cyan,\n  Colors.cyanAccent,\n  Colors.teal,\n  Colors.tealAccent,\n  Colors.green,\n  Colors.greenAccent,\n  Colors.lightGreen,\n  Colors.lightGreenAccent,\n  Colors.lime,\n  Colors.limeAccent,\n  Colors.yellow,\n  Colors.yellowAccent,\n  Colors.amber,\n  Colors.amberAccent,\n  Colors.orange,\n  Colors.orangeAccent,\n  Colors.deepOrange,\n  Colors.deepOrangeAccent,\n  Colors.brown,\n  Colors.grey,\n  Colors.blueGrey\n];\n"
  },
  {
    "path": "lib/src/widgets/color_picker/material_color_picker.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport 'circle_color.dart';\nimport 'colors.dart';\n\nclass MaterialColorPicker extends StatefulWidget {\n  final Color? selectedColor;\n  final ValueChanged<Color?>? onColorChange;\n  final ValueChanged<ColorSwatch>? onMainColorChange;\n  final List<ColorSwatch>? colors;\n  final bool shrinkWrap;\n  final ScrollPhysics? physics;\n  final bool allowShades;\n  final bool onlyShadeSelection;\n  final double circleSize;\n  final double spacing;\n  final IconData iconSelected;\n  final VoidCallback? onBack;\n  final double? elevation;\n\n  const MaterialColorPicker({\n    super.key,\n    this.selectedColor,\n    this.onColorChange,\n    this.onMainColorChange,\n    this.colors,\n    this.shrinkWrap = false,\n    this.physics,\n    this.allowShades = true,\n    this.onlyShadeSelection = false,\n    this.iconSelected = Icons.check,\n    this.circleSize = 45.0,\n    this.spacing = 9.0,\n    this.onBack,\n    this.elevation,\n  });\n\n  @override\n  State<MaterialColorPicker> createState() => _MaterialColorPickerState();\n}\n\nclass _MaterialColorPickerState extends State<MaterialColorPicker> {\n  final _defaultValue = materialColors[0];\n\n  List<ColorSwatch>? _colors = materialColors;\n\n  ColorSwatch? _mainColor;\n  Color? _shadeColor;\n  late bool _isMainSelection;\n\n  @override\n  void initState() {\n    super.initState();\n    _initSelectedValue();\n  }\n\n  @protected\n  @override\n  void didUpdateWidget(covariant MaterialColorPicker oldWidget) {\n    _initSelectedValue();\n    super.didUpdateWidget(oldWidget);\n  }\n\n  void _initSelectedValue() {\n    if (widget.colors != null) _colors = widget.colors;\n\n    Color? shadeColor = widget.selectedColor ?? _defaultValue;\n    var mainColor = _findMainColor(shadeColor);\n\n    if (mainColor == null) {\n      mainColor = _colors![0];\n      shadeColor = mainColor[500] ?? mainColor[400]!;\n    }\n\n    setState(() {\n      _mainColor = mainColor;\n      _shadeColor = shadeColor;\n      _isMainSelection = true;\n    });\n  }\n\n  ColorSwatch? _findMainColor(Color? shadeColor) {\n    for (final mainColor in _colors!) {\n      if (_isShadeOfMain(mainColor, shadeColor)) return mainColor;\n    }\n\n    return (shadeColor is ColorSwatch && _colors!.contains(shadeColor))\n        ? shadeColor\n        : null;\n  }\n\n  bool _isShadeOfMain(ColorSwatch mainColor, Color? shadeColor) {\n    for (final shade in _getMaterialColorShades(mainColor)) {\n      if (shade == shadeColor) return true;\n    }\n    return false;\n  }\n\n  void _onMainColorSelected(ColorSwatch color) {\n    var isShadeOfMain = _isShadeOfMain(color, _shadeColor);\n    final shadeColor = isShadeOfMain ? _shadeColor : (color[500] ?? color[400]);\n\n    setState(() {\n      _mainColor = color;\n      _shadeColor = shadeColor;\n      _isMainSelection = false;\n    });\n    if (widget.onMainColorChange != null) widget.onMainColorChange!(color);\n    if (widget.onlyShadeSelection && !_isMainSelection) {\n      return;\n    }\n    if (widget.allowShades && widget.onColorChange != null) {\n      widget.onColorChange!(shadeColor);\n    }\n  }\n\n  void _onShadeColorSelected(Color? color) {\n    setState(() => _shadeColor = color);\n    if (widget.onColorChange != null) widget.onColorChange!(color);\n  }\n\n  void _onBack() {\n    setState(() => _isMainSelection = true);\n    if (widget.onBack != null) widget.onBack!();\n  }\n\n  List<Widget> _buildListMainColor(List<ColorSwatch> colors) {\n    return [\n      for (final color in colors)\n        CircleColor(\n          color: color,\n          circleSize: widget.circleSize,\n          onColorChoose: () => _onMainColorSelected(color),\n          isSelected: _mainColor == color,\n          iconSelected: widget.iconSelected,\n          elevation: widget.elevation,\n        )\n    ];\n  }\n\n  List<Color?> _getMaterialColorShades(ColorSwatch color) {\n    return <Color?>[\n      if (color[50] != null) color[50],\n      if (color[100] != null) color[100],\n      if (color[200] != null) color[200],\n      if (color[300] != null) color[300],\n      if (color[400] != null) color[400],\n      if (color[500] != null) color[500],\n      if (color[600] != null) color[600],\n      if (color[700] != null) color[700],\n      if (color[800] != null) color[800],\n      if (color[900] != null) color[900],\n    ];\n  }\n\n  List<Widget> _buildListShadesColor(ColorSwatch color) {\n    return [\n      IconButton(\n        icon: const Icon(Icons.arrow_back),\n        onPressed: _onBack,\n        padding: const EdgeInsets.only(right: 2.0),\n      ),\n      for (final color in _getMaterialColorShades(color))\n        CircleColor(\n          color: color!,\n          circleSize: widget.circleSize,\n          onColorChoose: () => _onShadeColorSelected(color),\n          isSelected: _shadeColor == color,\n          iconSelected: widget.iconSelected,\n          elevation: widget.elevation,\n        ),\n    ];\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    final listChildren = _isMainSelection || !widget.allowShades\n        ? _buildListMainColor(_colors!)\n        : _buildListShadesColor(_mainColor!);\n\n    // Size of dialog\n    final width = MediaQuery.of(context).size.width * .80;\n    // Number of circle per line, depend on width and circleSize\n    final nbrCircleLine = width ~/ (widget.circleSize + widget.spacing);\n\n    return SizedBox(\n      width: width,\n      child: GridView.count(\n        shrinkWrap: widget.shrinkWrap,\n        physics: widget.physics,\n        padding: const EdgeInsets.all(16.0),\n        crossAxisSpacing: widget.spacing,\n        mainAxisSpacing: widget.spacing,\n        crossAxisCount: nbrCircleLine,\n        children: listChildren,\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/src/widgets/settings_widgets.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter/services.dart';\nimport 'package:flutter_settings_screens/flutter_settings_screens.dart';\nimport 'package:flutter_settings_screens/src/utils/widget_utils.dart';\n\nimport 'color_picker/material_color_picker.dart';\n\npart 'base_widgets.dart';\n\n/// --------- Types of Settings widgets ---------- ///\n\n/// [SimpleSettingsTile] is a simple settings tile that can open a new screen\n/// by tapping the tile.\n///\n/// Example:\n/// ```dart\n/// SimpleSettingsTile(\n///   title: 'Advanced',\n///   subtitle: 'More, advanced settings.'\n///   child: SettingsScreen(\n///     title: 'Sub menu',\n///     children: <Widget>[\n///       CheckboxSettingsTile(\n///         settingsKey: 'key-of-your-setting',\n///         title: 'This is a simple Checkbox',\n///       ),\n///     ],\n///   ),\n/// );\n/// ```\nclass SimpleSettingsTile extends StatelessWidget {\n  /// title string for the tile\n  final String title;\n\n  /// subtitle string for the tile\n  final String? subtitle;\n\n  /// title text style\n  final TextStyle? titleTextStyle;\n\n  /// subtitle text style\n  final TextStyle? subtitleTextStyle;\n\n  /// widget to be placed at first in the tile\n  final Widget? leading;\n\n  /// flag which represents the state of the settings, if false the the tile will\n  /// ignore all the user inputs, default = true\n  final bool enabled;\n\n  /// widget that will be displayed on tap of the tile\n  final Widget? child;\n\n  final VoidCallback? onTap;\n\n  final bool showDivider;\n\n  const SimpleSettingsTile({\n    super.key,\n    required this.title,\n    this.subtitle,\n    this.titleTextStyle,\n    this.subtitleTextStyle,\n    this.child,\n    this.enabled = true,\n    this.leading,\n    this.onTap,\n    this.showDivider = true,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return _SettingsTile(\n      leading: leading,\n      title: title,\n      subtitle: subtitle,\n      titleTextStyle: titleTextStyle,\n      subtitleTextStyle: subtitleTextStyle,\n      enabled: enabled,\n      onTap: () => _handleTap(context),\n      showDivider: showDivider,\n      child: child != null ? getIcon(context) : const Text(''),\n    );\n  }\n\n  Widget getIcon(BuildContext context) {\n    return IconButton(\n      icon: const Icon(Icons.navigate_next),\n      onPressed: enabled ? () => _handleTap(context) : null,\n    );\n  }\n\n  void _handleTap(BuildContext context) {\n    onTap?.call();\n\n    if (child != null) {\n      Navigator.of(context).push(MaterialPageRoute(\n        builder: (BuildContext context) => child!,\n      ));\n    }\n  }\n}\n\n/// [ModalSettingsTile] is a widget which allows creating\n/// a setting which shows the [children] in a [_ModalSettingsTile]\n///\n/// Example:\n/// ```dart\n///  ModalSettingsTile(\n///    title: 'Quick setting dialog',\n///    subtitle: 'Settings on a dialog',\n///    children: <Widget>[\n///      CheckboxSettingsTile(\n///        settingKey: 'key-day-light-savings',\n///        title: 'Daylight Time Saving',\n///        enabledLabel: 'Enabled',\n///        disabledLabel: 'Disabled',\n///        leading: Icon(Icons.timelapse),\n///      ),\n///      SwitchSettingsTile(\n///        settingKey: 'key-dark-mode',\n///        title: 'Dark Mode',\n///        enabledLabel: 'Enabled',\n///        disabledLabel: 'Disabled',\n///        leading: Icon(Icons.palette),\n///      ),\n///    ],\n///  );\n///\n/// ```\n///\nclass ModalSettingsTile<T> extends StatelessWidget {\n  /// title string for the tile\n  final String title;\n\n  /// subtitle string for the tile\n  final String subtitle;\n\n  /// title text style\n  final TextStyle? titleTextStyle;\n\n  /// subtitle text style\n  final TextStyle? subtitleTextStyle;\n\n  /// widget to be placed at first in the tile\n  final Widget? leading;\n\n  /// flag which represents the state of the settings, if false the the tile will\n  /// ignore all the user inputs, default = true\n  final bool enabled;\n\n  /// List of widgets which are to be shown in the modal dialog\n  final List<Widget> children;\n\n  final bool showConfirmation;\n  final VoidCallback? onCancel;\n  final OnConfirmedCallback? onConfirm;\n\n  const ModalSettingsTile({\n    super.key,\n    required this.title,\n    required this.children,\n    this.subtitle = '',\n    this.enabled = true,\n    this.leading,\n    this.showConfirmation = false,\n    this.onCancel,\n    this.onConfirm,\n    this.titleTextStyle,\n    this.subtitleTextStyle,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return _ModalSettingsTile<T>(\n      leading: leading,\n      title: title,\n      subtitle: subtitle,\n      titleTextStyle: titleTextStyle,\n      subtitleTextStyle: subtitleTextStyle,\n      enabled: enabled,\n      onCancel: onCancel,\n      onConfirm: onConfirm,\n      showConfirmation: showConfirmation,\n      children: children,\n    );\n  }\n}\n\n/// [ExpandableSettingsTile] is wrapper widget which shows the\n/// given [children] in an [_ExpansionSettingsTile]\n///\n/// Example:\n/// ```dart\n///  ExpandableSettingsTile(\n///    title: 'Quick setting dialog2',\n///    subtitle: 'Expandable Settings',\n///    onExpansionChanged: (state) {\n///      _bolusExpanded = state;\n///    },\n///    children: <Widget>[\n///      CheckboxSettingsTile(\n///        settingKey: 'key-day-light-savings',\n///        title: 'Daylight Time Saving',\n///        enabledLabel: 'Enabled',\n///        disabledLabel: 'Disabled',\n///        leading: Icon(Icons.timelapse),\n///      ),\n///      SwitchSettingsTile(\n///        settingKey: 'key-dark-mode',\n///        title: 'Dark Mode',\n///        enabledLabel: 'Enabled',\n///        disabledLabel: 'Disabled',\n///        leading: Icon(Icons.palette),\n///      ),\n///    ],\n///  );\n///\n/// ```\nclass ExpandableSettingsTile extends StatelessWidget {\n  /// title string for the tile\n  final String title;\n\n  /// subtitle string for the tile\n  final String subtitle;\n\n  /// title text style\n  final TextStyle? titleTextStyle;\n\n  /// subtitle text style\n  final TextStyle? subtitleTextStyle;\n\n  /// widget to be placed at first in the tile\n  final Widget? leading;\n\n  /// flag which represents the state of the settings, if false the the tile will\n  /// ignore all the user inputs, default = true\n  final bool enabled;\n\n  /// List of the widgets which are to be shown when tile is expanded\n  final List<Widget> children;\n\n  /// flag which represents the initial state of the tile, if true the tile state is\n  /// set to expanded initially, default = false\n  final bool expanded;\n\n  /// A Callback for the change of the Expansion state\n  final Function(bool)? onExpansionChanged;\n\n  final bool showDivider;\n\n  const ExpandableSettingsTile({\n    super.key,\n    required this.title,\n    required this.children,\n    this.subtitle = '',\n    this.enabled = true,\n    this.expanded = false,\n    this.onExpansionChanged,\n    this.leading,\n    this.titleTextStyle,\n    this.subtitleTextStyle,\n    this.showDivider = true,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return _ExpansionSettingsTile(\n      leading: leading,\n      title: title,\n      subtitle: subtitle,\n      titleTextStyle: titleTextStyle,\n      subtitleTextStyle: subtitleTextStyle,\n      enabled: enabled,\n      expanded: expanded,\n      onExpansionChanged: onExpansionChanged,\n      showDivider: showDivider,\n      child: SettingsContainer(\n        children: children,\n      ),\n    );\n  }\n}\n\n/// [SettingsContainer] is a widget that helps its child or children to fit in\n/// the settings screen. It is helpful if you want to place other widgets than\n/// settings tiles in the settings screen body.\n/// Example:\n/// ```dart\n/// SettingsContainer(\n/// \tchildren: <Widget>[\n/// \t\tText('First line'),\n/// \t\tText('Second line'),\n///     Icon(Icons.palette),\n/// \t],\n/// );\n/// ```\nclass SettingsContainer extends StatelessWidget {\n  /// List of widgets which will be shown as Custom list of setting tile\n  final List<Widget> children;\n\n  /// flag to represent if this Container allows internal scrolling of the widgets\n  /// along with the outer settings screen/container,\n  /// if true, the list of widget inside are made scrollable, default = true\n  final bool allowScrollInternally;\n\n  final double leftPadding;\n\n  const SettingsContainer({\n    super.key,\n    required this.children,\n    this.allowScrollInternally = false,\n    this.leftPadding = 0.0,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return _buildChild();\n  }\n\n  Widget _buildChild() {\n    var child = allowScrollInternally ? getList(children) : getColumn(children);\n    return Padding(\n      padding: const EdgeInsets.only(\n        top: 0.0,\n      ),\n      child: Material(\n        child: Container(\n          padding: EdgeInsets.only(left: leftPadding),\n          child: child,\n        ),\n      ),\n    );\n  }\n\n  Widget getList(List<Widget> children) {\n    return ListView.builder(\n      itemBuilder: (context, index) {\n        return children[index];\n      },\n      shrinkWrap: true,\n      itemCount: children.length,\n    );\n  }\n\n  Widget getColumn(List<Widget> children) {\n    return Column(\n      mainAxisSize: MainAxisSize.max,\n      crossAxisAlignment: CrossAxisAlignment.stretch,\n      children: children,\n    );\n  }\n}\n\n/// [SettingsGroup] is a widget that contains multiple settings tiles and other\n/// widgets together as a group and shows a title/name of that group.\n///\n/// All the children widget will have a small padding from the left and top\n/// to provide a sense that they in a separate group from others\n///\n///  Example:\n///\n/// ```dart\n/// SettingsGroup(\n///    title: 'Group title',\n///    children: <Widget>[\n///       CheckboxSettingsTile(\n///         settingKey: 'key-day-light-savings',\n///         title: 'Daylight Time Saving',\n///         enabledLabel: 'Enabled',\n///         disabledLabel: 'Disabled',\n///         leading: Icon(Icons.timelapse),\n///       ),\n///       SwitchSettingsTile(\n///         settingKey: 'key-dark-mode',\n///         title: 'Dark Mode',\n///         enabledLabel: 'Enabled',\n///         disabledLabel: 'Disabled',\n///         leading: Icon(Icons.palette),\n///       ),\n///  \t],\n///  );\n/// ```\nclass SettingsGroup extends StatelessWidget {\n  /// title string for the tile\n  final String title;\n\n  /// subtitle string for the tile\n  final String subtitle;\n\n  /// title text style\n  final TextStyle? titleTextStyle;\n\n  /// subtitle text style\n  final TextStyle? subtitleTextStyle;\n\n  /// List of the widgets which are to be shown under the title as a group\n  final List<Widget> children;\n\n  final Alignment titleAlignment;\n\n  const SettingsGroup({\n    super.key,\n    required this.title,\n    required this.children,\n    this.subtitle = '',\n    this.titleTextStyle,\n    this.subtitleTextStyle,\n    this.titleAlignment = Alignment.centerLeft,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    var elements = <Widget>[\n      Container(\n        padding: const EdgeInsets.only(top: 16.0, left: 16.0, right: 22.0),\n        child: Align(\n          alignment: titleAlignment,\n          child: Text(\n            title.toUpperCase(),\n            style: titleTextStyle ?? groupStyle(context),\n          ),\n        ),\n      ),\n    ];\n\n    if (subtitle.isNotEmpty) {\n      elements.addAll([\n        Container(\n          padding: const EdgeInsets.all(16.0),\n          child: Align(\n            alignment: Alignment.centerLeft,\n            child: Text(\n              subtitle,\n              style: subtitleTextStyle,\n            ),\n          ),\n        ),\n        _SettingsTileDivider(),\n      ]);\n    }\n    elements.addAll(children);\n    return Wrap(\n      children: <Widget>[\n        Column(\n          children: elements,\n        )\n      ],\n    );\n  }\n\n  TextStyle groupStyle(BuildContext context) {\n    return TextStyle(\n      color: Theme.of(context).colorScheme.secondary,\n      fontSize: 12.0,\n      fontWeight: FontWeight.bold,\n    );\n  }\n}\n\n/// --------- Common Settings widgets ---------- ///\n\n/// A Setting widget which allows user a text input in a [TextFormField]\n///\n/// This widget by default is a [_ModalSettingsTile]. Meaning, this input field\n/// will be shown in a dialog view.\n///\n/// Example:\n///\n/// ```dart\n/// TextInputSettingsTile(\n///   title: 'User Name',\n///   settingKey: 'key-user-name',\n///   initialValue: 'admin',\n///   validator: (String username) {\n///     if (username != null && username.length > 3) {\n///       return null;\n///     }\n///     return \"User Name can't be smaller than 4 letters\";\n///   },\n///   borderColor: Colors.blueAccent,\n///   errorColor: Colors.deepOrangeAccent,\n/// );\n///\n/// ```\n///\n///  OR\n///\n/// ``` dart\n/// TextInputSettingsTile(\n///   title: 'password',\n///   settingKey: 'key-user-password',\n///   obscureText: true,\n///   validator: (String password) {\n///     if (password != null && password.length > 6) {\n///       return null;\n///     }\n///     return \"Password can't be smaller than 7 letters\";\n///   },\n///   borderColor: Colors.blueAccent,\n///   errorColor: Colors.deepOrangeAccent,\n/// );\n/// ```\nclass TextInputSettingsTile extends StatefulWidget {\n  /// Settings Key string for storing the text in cache (assumed to be unique)\n  final String settingKey;\n\n  /// initial value to be filled in the text field, default = ''\n  final String initialValue;\n\n  /// title for the settings tile\n  final String title;\n\n  /// title text style\n  final TextStyle? titleTextStyle;\n\n  /// subtitle text style\n  final TextStyle? subtitleTextStyle;\n\n  /// flag which represents the state of the settings, if false the the tile will\n  /// ignore all the user inputs, default = true\n  final bool enabled;\n\n  /// Validation mode helps use customize the way the input text field is\n  /// validated for proper input values.\n  ///\n  /// [AutovalidateMode.disabled] - Never auto validate, equivalent of `autoValidate = false`\n  /// [AutovalidateMode.always] - Always auto validate, equivalent of `autoValidate = true`\n  /// [AutovalidateMode.onUserInteraction] - Only auto validate if user interacts with it\n  final AutovalidateMode autovalidateMode;\n\n  /// flag which represents if the text field will be focused by default\n  /// or not\n  /// if true, then the text field will be in focus other wise it will not be\n  /// in focus by default, default = true\n  final bool autoFocus;\n\n  /// flag which represents if the text will be automatically selected on focus\n  final bool selectAllOnFocus;\n\n  /// on change callback for handling the value change\n  final OnChanged<String>? onChange;\n\n  /// validator for input validation\n  final FormFieldValidator<String?>? validator;\n\n  /// flag which represents the state of obscureText in the [TextFormField]\n  ///  default = false\n  final bool obscureText;\n\n  /// Color of the border of the [TextFormField]\n  final Color? borderColor;\n\n  /// Color of the border of the [TextFormField], when there's an error\n  /// or input is not passed through the validation\n  final Color? errorColor;\n\n  /// [TextInputType] of the [TextFormField] to set the keyboard type to name, phone, etc.\n  final TextInputType? keyboardType;\n\n  /// form helper text\n  final String? helperText;\n\n  /// list of inputFormatters\n  final List<TextInputFormatter>? inputFormatters;\n\n  const TextInputSettingsTile({\n    super.key,\n    required this.title,\n    required this.settingKey,\n    this.initialValue = '',\n    this.enabled = true,\n    this.autovalidateMode = AutovalidateMode.onUserInteraction,\n    this.autoFocus = true,\n    this.selectAllOnFocus = false,\n    this.onChange,\n    this.validator,\n    this.obscureText = false,\n    this.borderColor,\n    this.errorColor,\n    this.keyboardType,\n    this.titleTextStyle,\n    this.subtitleTextStyle,\n    this.helperText,\n    this.inputFormatters,\n  });\n\n  @override\n  State<TextInputSettingsTile> createState() => _TextInputSettingsTileState();\n}\n\nclass _TextInputSettingsTileState extends State<TextInputSettingsTile> {\n  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();\n  late TextEditingController _controller;\n  late FocusNode _focusNode;\n\n  @override\n  void initState() {\n    super.initState();\n    _controller = TextEditingController();\n    _focusNode = FocusNode();\n    _focusNode.addListener(() {\n      if (widget.selectAllOnFocus) {\n        _controller.selection =\n            TextSelection(baseOffset: 0, extentOffset: _controller.text.length);\n      }\n    });\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return ValueChangeObserver<String>(\n      cacheKey: widget.settingKey,\n      defaultValue: widget.initialValue,\n      builder:\n          (BuildContext context, String value, OnChanged<String> onChanged) {\n        WidgetsBinding.instance.addPostFrameCallback((_) {\n          _controller.text = value;\n        });\n        return SettingsContainer(\n          children: [\n            _ModalSettingsTile<String>(\n              title: widget.title,\n              subtitle: widget.obscureText ? '' : value,\n              titleTextStyle: widget.titleTextStyle,\n              subtitleTextStyle: widget.subtitleTextStyle,\n              enabled: widget.enabled,\n              showConfirmation: true,\n              onConfirm: () => _submitText(_controller.text),\n              onCancel: () {\n                _controller.text = Settings.getValue(widget.settingKey) ?? '';\n              },\n              children: <Widget>[\n                _buildTextField(context, value, onChanged),\n              ],\n            ),\n          ],\n        );\n      },\n    );\n  }\n\n  Widget _buildTextField(\n      BuildContext context, String value, OnChanged<String> onChanged) {\n    final borderColor = widget.borderColor ?? Colors.blue;\n    final errorColor = widget.errorColor ?? Colors.red;\n\n    return Padding(\n      padding: const EdgeInsets.all(16.0),\n      child: Form(\n        key: _formKey,\n        child: TextFormField(\n          autofocus: widget.autoFocus,\n          controller: _controller,\n          focusNode: _focusNode,\n          autovalidateMode: widget.autovalidateMode,\n          enabled: widget.enabled,\n          validator: widget.enabled ? widget.validator : null,\n          onSaved: widget.enabled ? (value) => _onSave(value, onChanged) : null,\n          obscureText: widget.obscureText,\n          keyboardType: widget.keyboardType,\n          cursorColor: borderColor,\n          inputFormatters: widget.inputFormatters ?? [],\n          decoration: InputDecoration(\n            helperText: widget.helperText,\n            errorMaxLines: 3,\n            helperMaxLines: 3,\n            errorStyle: TextStyle(\n              color: errorColor,\n            ),\n            errorBorder: OutlineInputBorder(\n              borderRadius: const BorderRadius.all(\n                Radius.circular(5.0),\n              ),\n              borderSide: BorderSide(color: errorColor),\n            ),\n            border: OutlineInputBorder(\n              borderRadius: const BorderRadius.all(\n                Radius.circular(5.0),\n              ),\n              borderSide: BorderSide(\n                color: borderColor,\n              ),\n            ),\n            focusedBorder: OutlineInputBorder(\n              borderRadius: const BorderRadius.all(\n                Radius.circular(5.0),\n              ),\n              borderSide: BorderSide(\n                color: borderColor,\n              ),\n            ),\n          ),\n        ),\n      ),\n    );\n  }\n\n  bool _submitText(String newValue) {\n    var isValid = true;\n    final state = _formKey.currentState;\n    if (state != null) {\n      isValid = state.validate();\n    }\n\n    if (isValid) {\n      state?.save();\n      return true;\n    }\n\n    return false;\n  }\n\n  void _onSave(String? newValue, OnChanged<String> onChanged) {\n    if (newValue == null) return;\n    WidgetsBinding.instance.addPostFrameCallback((_) {\n      onChanged(newValue);\n      widget.onChange?.call(newValue);\n    });\n  }\n}\n\n/// [SwitchSettingsTile] is a widget that has a [Switch] with given title,\n/// subtitle and default value/status of the switch\n///\n/// This widget supports an additional list of widgets to display\n/// when the switch is enabled. These optional list of widgets is accessed\n/// through `childrenIfEnabled` property of this widget.\n///\n/// This widget works similar to [CheckboxSettingsTile].\n///\n///  Example:\n///\n/// ```dart\n///  SwitchSettingsTile(\n///   leading: Icon(Icons.developer_mode),\n///   settingKey: 'key-switch-dev-mode',\n///   title: 'Developer Settings',\n///   onChange: (value) {\n///     debugPrint('key-switch-dev-mod: $value');\n///   },\n///   childrenIfEnabled: <Widget>[\n///     CheckboxSettingsTile(\n///       leading: Icon(Icons.adb),\n///       settingKey: 'key-is-developer',\n///       title: 'Developer Mode',\n///       onChange: (value) {\n///         debugPrint('key-is-developer: $value');\n///       },\n///     ),\n///     SwitchSettingsTile(\n///       leading: Icon(Icons.usb),\n///       settingKey: 'key-is-usb-debugging',\n///       title: 'USB Debugging',\n///       onChange: (value) {\n///         debugPrint('key-is-usb-debugging: $value');\n///       },\n///     ),\n///     SimpleSettingsTile(\n///       title: 'Root Settings',\n///       subtitle: 'These settings is not accessible',\n///       enabled: false,\n///     )\n///   ],\n///  );\n///  ```\nclass SwitchSettingsTile extends StatelessWidget {\n  /// Settings Key string for storing the state of switch in cache (assumed to be unique)\n  final String settingKey;\n\n  /// initial value to be used as state of the switch, default = false\n  final bool defaultValue;\n\n  /// title for the settings tile\n  final String title;\n\n  /// subtitle for the settings tile, default = ''\n  final String subtitle;\n\n  /// title text style\n  final TextStyle? titleTextStyle;\n\n  /// subtitle text style\n  final TextStyle? subtitleTextStyle;\n\n  /// flag which represents the state of the settings, if false the the tile will\n  /// ignore all the user inputs, default = true\n  final bool enabled;\n\n  /// on change callback for handling the value change\n  final OnChanged<bool>? onChange;\n\n  /// A Widget that will be displayed in the front of the tile\n  final Widget? leading;\n\n  /// A specific text that will be displayed as subtitle when switch is set to enable state\n  /// if provided, default = ''\n  final String enabledLabel;\n\n  /// A specific text that will be displayed as subtitle when switch is set to disable state\n  /// if provided, default = ''\n  final String disabledLabel;\n\n  /// A List of widgets that will be displayed when the switch is set to enable\n  /// state, Any flutter widget can be added in this list\n  final List<Widget>? childrenIfEnabled;\n\n  final Color? activeColor;\n\n  final bool showDivider;\n\n  const SwitchSettingsTile({\n    super.key,\n    required this.title,\n    required this.settingKey,\n    this.defaultValue = false,\n    this.enabled = true,\n    this.onChange,\n    this.leading,\n    this.enabledLabel = '',\n    this.disabledLabel = '',\n    this.childrenIfEnabled,\n    this.subtitle = '',\n    this.titleTextStyle,\n    this.subtitleTextStyle,\n    this.activeColor,\n    this.showDivider = true,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return ValueChangeObserver<bool>(\n      cacheKey: settingKey,\n      defaultValue: defaultValue,\n      builder: (BuildContext context, bool value, OnChanged<bool> onChanged) {\n        Widget mainWidget = _SettingsTile(\n          leading: leading,\n          title: title,\n          subtitle: getSubtitle(value),\n          onTap: () => _onSwitchChange(context, !value, onChanged),\n          enabled: enabled,\n          titleTextStyle: titleTextStyle,\n          subtitleTextStyle: subtitleTextStyle,\n          showDivider: showDivider,\n          child: _SettingsSwitch(\n            value: value,\n            onChanged: (value) => _onSwitchChange(context, value, onChanged),\n            enabled: enabled,\n            activeColor: activeColor,\n          ),\n        );\n\n        var finalWidget = getFinalWidget(\n          context,\n          mainWidget,\n          value,\n          childrenIfEnabled,\n        );\n        return finalWidget;\n      },\n    );\n  }\n\n  Future<void> _onSwitchChange(\n      BuildContext context, bool? value, OnChanged<bool> onChanged) async {\n    if (value == null) return;\n    onChanged(value);\n    onChange?.call(value);\n  }\n\n  String getSubtitle(bool currentStatus) {\n    if (subtitle.isNotEmpty) {\n      return subtitle;\n    }\n    var label = '';\n    if (currentStatus && enabledLabel.isNotEmpty) {\n      label = enabledLabel;\n    }\n    if (!currentStatus && disabledLabel.isNotEmpty) {\n      label = disabledLabel;\n    }\n    return label;\n  }\n\n  Widget getFinalWidget(BuildContext context, Widget mainWidget,\n      bool currentValue, List<Widget>? childrenIfEnabled) {\n    if (childrenIfEnabled == null || !currentValue) {\n      return SettingsContainer(\n        children: [mainWidget],\n      );\n    }\n    final children = getPaddedParentChildrenList(childrenIfEnabled);\n    children.insert(0, mainWidget);\n\n    return SettingsContainer(\n      children: children,\n    );\n  }\n}\n\n/// [CheckboxSettingsTile] is a widget that has a [Checkbox] with given title,\n/// subtitle and default value/status of the Checkbox\n///\n/// This widget supports an additional list of widgets to display\n/// when the Checkbox is checked. These optional list of widgets is accessed\n/// through `childrenIfEnabled` property of this widget.\n///\n/// This widget works similar to [SwitchSettingsTile].\n///\n///  Example:\n///\n/// ```dart\n///  CheckboxSettingsTile(\n///   leading: Icon(Icons.developer_mode),\n///   settingKey: 'key-check-box-dev-mode',\n///   title: 'Developer Settings',\n///   onChange: (value) {\n///     debugPrint('key-check-box-dev-mode: $value');\n///   },\n///   childrenIfEnabled: <Widget>[\n///     CheckboxSettingsTile(\n///       leading: Icon(Icons.adb),\n///       settingKey: 'key-is-developer',\n///       title: 'Developer Mode',\n///       onChange: (value) {\n///         debugPrint('key-is-developer: $value');\n///       },\n///     ),\n///     SwitchSettingsTile(\n///       leading: Icon(Icons.usb),\n///       settingKey: 'key-is-usb-debugging',\n///       title: 'USB Debugging',\n///       onChange: (value) {\n///         debugPrint('key-is-usb-debugging: $value');\n///       },\n///     ),\n///   ],\n///  );\n///  ```\nclass CheckboxSettingsTile extends StatelessWidget {\n  /// Settings Key string for storing the state of checkbox in cache (assumed to be unique)\n  final String settingKey;\n\n  /// initial value to be used as state of the checkbox, default = false\n  final bool defaultValue;\n\n  /// title for the settings tile\n  final String title;\n\n  /// subtitle for the settings tile, default = ''\n  final String subtitle;\n\n  /// title text style\n  final TextStyle? titleTextStyle;\n\n  /// subtitle text style\n  final TextStyle? subtitleTextStyle;\n\n  /// flag which represents the state of the settings, if false the the tile will\n  /// ignore all the user inputs, default = true\n  final bool enabled;\n\n  /// on change callback for handling the value change\n  final OnChanged<bool>? onChange;\n\n  /// A Widget that will be displayed in the front of the tile\n  final Widget? leading;\n\n  /// A specific text that will be displayed as subtitle when checkbox is set to enable state\n  /// if provided, default = ''\n  final String enabledLabel;\n\n  /// A specific text that will be displayed as subtitle when checkbox is set to disable state\n  /// if provided, default = ''\n  final String disabledLabel;\n\n  /// A List of widgets that will be displayed when the checkbox is set to enable\n  /// state, Any flutter widget can be added in this list\n  final List<Widget>? childrenIfEnabled;\n\n  final bool showDivider;\n\n  const CheckboxSettingsTile({\n    super.key,\n    required this.title,\n    required this.settingKey,\n    this.defaultValue = false,\n    this.enabled = true,\n    this.onChange,\n    this.leading,\n    this.enabledLabel = '',\n    this.disabledLabel = '',\n    this.childrenIfEnabled,\n    this.subtitle = '',\n    this.titleTextStyle,\n    this.subtitleTextStyle,\n    this.showDivider = true,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return ValueChangeObserver<bool>(\n      cacheKey: settingKey,\n      defaultValue: defaultValue,\n      builder: (BuildContext context, bool value, OnChanged<bool> onChanged) {\n        var mainWidget = _SettingsTile(\n          leading: leading,\n          title: title,\n          enabled: enabled,\n          subtitle: getSubtitle(value),\n          onTap: () => _onCheckboxChange(!value, onChanged),\n          titleTextStyle: titleTextStyle,\n          subtitleTextStyle: subtitleTextStyle,\n          showDivider: showDivider,\n          child: _SettingsCheckbox(\n            value: value,\n            onChanged: (value) => _onCheckboxChange(value, onChanged),\n            enabled: enabled,\n          ),\n        );\n\n        var finalWidget = getFinalWidget(\n          context,\n          mainWidget,\n          value,\n          childrenIfEnabled,\n        );\n        return finalWidget;\n      },\n    );\n  }\n\n  Future<void> _onCheckboxChange(bool? value, OnChanged<bool> onChanged) async {\n    if (value == null) return;\n    onChanged(value);\n    onChange?.call(value);\n  }\n\n  String getSubtitle(bool currentStatus) {\n    if (subtitle.isNotEmpty) {\n      return subtitle;\n    }\n\n    var label = '';\n    if (currentStatus && enabledLabel.isNotEmpty) {\n      label = enabledLabel;\n    }\n    if (!currentStatus && disabledLabel.isNotEmpty) {\n      label = disabledLabel;\n    }\n    return label;\n  }\n\n  Widget getFinalWidget(BuildContext context, Widget mainWidget,\n      bool currentValue, List<Widget>? childrenIfEnabled) {\n    if (childrenIfEnabled == null || !currentValue) {\n      return SettingsContainer(\n        children: [mainWidget],\n      );\n    }\n    final children = getPaddedParentChildrenList(childrenIfEnabled);\n    children.insert(0, mainWidget);\n\n    return SettingsContainer(\n      children: children,\n    );\n  }\n}\n\n/// [RadioSettingsTile] is a widget that has a list of [Radio] widgets with given title,\n/// subtitle and default/group value which determines which Radio will be selected\n/// initially.\n///\n/// This widget support Any type of values which should be put in the preference.\n/// However, since any types of the value is supported, the input for this widget\n/// is a Map to the required values with their string representation.\n///\n/// For example if the required value type is a boolean then the values map can\n/// be as following:\n///  <bool, String> {\n///     true: 'Enabled',\n///     false: 'Disabled'\n///  }\n///\n/// So, if the `Enabled` value radio is selected then the value `true` will be\n/// stored in the preference\n///\n/// Complete Example:\n///\n/// ```dart\n/// RadioSettingsTile<int>(\n///   title: 'Preferred Sync Period',\n///   settingKey: 'key-radio-sync-period',\n///   values: <int, String>{\n///     0: 'Never',\n///     1: 'Daily',\n///     7: 'Weekly',\n///     15: 'Fortnight',\n///     30: 'Monthly',\n///   },\n///   selected: 0,\n///   onChange: (value) {\n///     debugPrint('key-radio-sync-period: $value days');\n///   },\n/// )\n/// ```\nclass RadioSettingsTile<T> extends StatefulWidget {\n  /// Settings Key string for storing the state of Radio buttons in cache (assumed to be unique)\n  final String settingKey;\n\n  /// Selected value in the radio button group otherwise known as group value\n  final T selected;\n\n  /// A map containing unique values along with the display name\n  final Map<T, String> values;\n\n  /// title for the settings tile\n  final String title;\n\n  /// subtitle for the settings tile, default = ''\n  final String subtitle;\n\n  /// title text style\n  final TextStyle? titleTextStyle;\n\n  /// subtitle text style\n  final TextStyle? subtitleTextStyle;\n\n  /// flag which represents the state of the settings, if false the the tile will\n  /// ignore all the user inputs, default = true\n  final bool enabled;\n\n  /// flag which allows showing the display names along with the radio button\n  final bool showTitles;\n\n  /// on change callback for handling the value change\n  final OnChanged<T>? onChange;\n\n  /// A Widget that will be displayed in the front of the tile\n  final Widget? leading;\n\n  final Color? activeColor;\n\n  final bool showDivider;\n\n  const RadioSettingsTile({\n    super.key,\n    required this.title,\n    required this.settingKey,\n    required this.selected,\n    required this.values,\n    this.enabled = true,\n    this.onChange,\n    this.leading,\n    this.showTitles = true,\n    this.subtitle = '',\n    this.titleTextStyle,\n    this.subtitleTextStyle,\n    this.activeColor,\n    this.showDivider = true,\n  });\n\n  @override\n  State<RadioSettingsTile<T>> createState() => _RadioSettingsTileState<T>();\n}\n\nclass _RadioSettingsTileState<T> extends State<RadioSettingsTile<T>> {\n  late T selectedValue;\n\n  @override\n  void initState() {\n    selectedValue = widget.selected;\n    super.initState();\n  }\n\n  Future<void> _onRadioChange(T? value, OnChanged<T> onChanged) async {\n    if (value == null) return;\n    selectedValue = value;\n    onChanged(value);\n    widget.onChange?.call(value);\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return ValueChangeObserver<T>(\n      cacheKey: widget.settingKey,\n      defaultValue: selectedValue,\n      builder: (BuildContext context, T value, OnChanged<T> onChanged) {\n        return SettingsContainer(\n          children: <Widget>[\n            Visibility(\n              visible: showTitles,\n              child: _SimpleHeaderTile(\n                title: widget.title,\n                subtitle: widget.subtitle.isNotEmpty\n                    ? widget.subtitle\n                    : widget.values[selectedValue],\n                leading: widget.leading,\n                titleTextStyle: widget.titleTextStyle,\n                subtitleTextStyle: widget.subtitleTextStyle,\n              ),\n            ),\n            _buildRadioTiles(context, value, onChanged, widget.activeColor)\n          ],\n        );\n      },\n    );\n  }\n\n  bool get showTitles => widget.showTitles;\n\n  Widget _buildRadioTiles(BuildContext context, T groupValue,\n      OnChanged<T> onChanged, Color? activeColor) {\n    var radioList =\n        widget.values.entries.map<Widget>((MapEntry<T, String> entry) {\n      return _SettingsTile(\n        title: entry.value,\n        titleTextStyle: widget.titleTextStyle,\n        onTap: () => _onRadioChange(entry.key, onChanged),\n        enabled: widget.enabled,\n        showDivider: widget.showDivider,\n        child: _SettingsRadio<T>(\n          value: entry.key,\n          onChanged: (newValue) => _onRadioChange(newValue, onChanged),\n          enabled: widget.enabled,\n          groupValue: groupValue,\n          activeColor: activeColor,\n        ),\n      );\n    }).toList();\n    return Column(\n      children: radioList,\n    );\n  }\n}\n\n/// [DropDownSettingsTile] is a widget that has a list of [DropdownMenuItem]s\n/// with given title, subtitle and default/group value which determines\n/// which value will be set to selected initially.\n///\n/// This widget support Any type of values which should be put in the preference.\n///\n/// However, since any types of the value is supported, the input for this widget\n/// is a Map to the required values with their string representation.\n///\n/// For example if the required value type is a boolean then the values map can\n/// be as following:\n///  <bool, String> {\n///     true: 'Enabled',\n///     false: 'Disabled'\n///  }\n///\n/// So, if the `Enabled` value is selected then the value `true` will be\n/// stored in the preference\n///\n/// Complete Example:\n///\n/// ```dart\n/// DropDownSettingsTile<int>(\n///   title: 'E-Mail View',\n///   settingKey: 'key-dropdown-email-view',\n///   values: <int, String>{\n///     2: 'Simple',\n///     3: 'Adjusted',\n///     4: 'Normal',\n///     5: 'Compact',\n///     6: 'Squeezed',\n///   },\n///   selected: 2,\n///   onChange: (value) {\n///     debugPrint('key-dropdown-email-view: $value');\n///   },\n/// );\n/// ```\nclass DropDownSettingsTile<T> extends StatefulWidget {\n  /// Settings Key string for storing the state of Radio buttons in cache (assumed to be unique)\n  final String settingKey;\n\n  /// Selected value in the radio button group otherwise known as group value\n  final T selected;\n\n  /// A map containing unique values along with the display name\n  final Map<T, String> values;\n\n  /// title for the settings tile\n  final String title;\n\n  /// subtitle for the settings tile, default = ''\n  final String subtitle;\n\n  /// title text style\n  final TextStyle? titleTextStyle;\n\n  /// subtitle text style\n  final TextStyle? subtitleTextStyle;\n\n  /// The widget shown in front of the title\n  final Widget? leading;\n\n  /// Alignment of the dropdown. Defaults to [AlignmentDirectional.centerEnd].\n  final AlignmentGeometry alignment;\n\n  /// flag which represents the state of the settings, if false the the tile will\n  /// ignore all the user inputs, default = true\n  final bool enabled;\n\n  /// on change callback for handling the value change\n  final OnChanged<T>? onChange;\n\n  final bool showDivider;\n\n  const DropDownSettingsTile({\n    super.key,\n    required this.title,\n    required this.settingKey,\n    required this.selected,\n    required this.values,\n    this.enabled = true,\n    this.onChange,\n    this.subtitle = '',\n    this.leading,\n    this.alignment = AlignmentDirectional.centerEnd,\n    this.titleTextStyle,\n    this.subtitleTextStyle,\n    this.showDivider = true,\n  });\n\n  @override\n  State<DropDownSettingsTile<T>> createState() =>\n      _DropDownSettingsTileState<T>();\n}\n\nclass _DropDownSettingsTileState<T> extends State<DropDownSettingsTile<T>> {\n  late T selectedValue;\n\n  @override\n  void initState() {\n    selectedValue = widget.selected;\n    super.initState();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return ValueChangeObserver<T>(\n      cacheKey: widget.settingKey,\n      defaultValue: selectedValue,\n      builder: (BuildContext context, T value, OnChanged<T> onChanged) {\n        return SettingsContainer(\n          children: <Widget>[\n            _SettingsTile(\n              title: widget.title,\n              subtitle: widget.subtitle,\n              leading: widget.leading,\n              enabled: widget.enabled,\n              titleTextStyle: widget.titleTextStyle,\n              subtitleTextStyle: widget.subtitleTextStyle,\n              showDivider: widget.showDivider,\n              child: _SettingsDropDown<T>(\n                selected: value,\n                alignment: widget.alignment,\n                values: widget.values.keys.toList().cast<T>(),\n                onChanged: (newValue) =>\n                    _handleDropDownChange(newValue, onChanged),\n                enabled: widget.enabled,\n                itemBuilder: (T value) {\n                  return Text(widget.values[value]!);\n                },\n              ),\n            )\n          ],\n        );\n      },\n    );\n  }\n\n  Future<void> _handleDropDownChange(T? value, OnChanged<T> onChanged) async {\n    if (value == null) return;\n    selectedValue = value;\n    onChanged(value);\n    widget.onChange?.call(value);\n  }\n}\n\n/// [SliderSettingsTile] is a widget that has a slider given title,\n/// subtitle and default value which determines what the slider's position\n/// will be set initially.\n///\n/// Example:\n///\n/// ```dart\n/// SliderSettingsTile(\n///  title: 'Volume',\n///  settingKey: 'key-slider-volume',\n///  defaultValue: 20,\n///  min: 0,\n///  max: 100,\n///  step: 1,\n///  leading: Icon(Icons.volume_up),\n///  onChange: (value) {\n///    debugPrint('key-slider-volume: $value');\n///  },\n/// );\n/// ```\nclass SliderSettingsTile extends StatefulWidget {\n  /// Settings Key string for storing the state of Slider in cache (assumed to be unique)\n  final String settingKey;\n\n  /// Selected value in the radio button group otherwise known as group value\n  /// default = 0.0\n  final double defaultValue;\n\n  /// title for the settings tile\n  final String title;\n\n  /// subtitle for the settings tile, default = ''\n  final String subtitle;\n\n  /// title text style\n  final TextStyle? titleTextStyle;\n\n  /// subtitle text style\n  final TextStyle? subtitleTextStyle;\n\n  /// flag which represents the state of the settings, if false the the tile will\n  /// ignore all the user inputs, default = true\n  final bool enabled;\n\n  /// flag which allows updating the value of setting immediately when the\n  /// slider is moved, default = true\n  ///\n  /// If this flag is enabled then [onChangeStart] & [onChangeEnd] callbacks are\n  /// ignored & will not be executed\n  ///\n  final bool eagerUpdate;\n\n  /// minimum allowed value for the slider, in other terms a start value\n  /// for the slider\n  final double min;\n\n  /// maximum allowed value for the slider, in other terms a end value\n  /// for the slider\n  final double max;\n\n  /// a step value which will be used to move the slider.\n  /// default = 1.0\n  ///\n  /// i.e. if the step = 1.0 then moving slider from left to right\n  /// will result in following values in order:\n  ///  1.0, 2.0, 3.0, 4.0, ..., 100.0\n  ///\n  /// if the step = 5.0 then the same slider movement will result in:\n  ///  5.0, 10.0, 15.0, 20.0, ..., 100.0\n  final double step;\n\n  /// on change callback for handling the value change\n  final OnChanged<double>? onChange;\n\n  /// callback for fetching the value slider movement starts\n  final OnChanged<double>? onChangeStart;\n\n  /// callback for fetching the value slider movement ends\n  final OnChanged<double>? onChangeEnd;\n\n  /// callback for fetching the value slider movement starts\n  final Widget? leading;\n\n  /// Value to be used as precision when printing the current value in widget\n  ///\n  /// Basically this value is used for input in [double.toStringAsFixed] method\n  /// while printing display value\n  ///\n  /// default = 2, you'll need to adjust the precision according to step value\n  ///\n  /// Note:\n  /// However this does not affect the actual value in the onChange callbacks\n  ///\n  /// For example:\n  ///  case 1:\n  ///   current value: 5.2500001\n  ///   decimalPrecision: 0\n  ///   result:\n  ///     callback value: 5.2500001\n  ///     display value: 5\n  ///\n  ///  case 2:\n  ///   current value: 5.2500001\n  ///   decimalPrecision: 1\n  ///   result:\n  ///     callback value: 5.2500001\n  ///     display value: 5.2\n  ///\n  ///  case 3:\n  ///   current value: 5.2500001\n  ///   decimalPrecision: 2\n  ///   result:\n  ///     callback value: 5.2500001\n  ///     display value: 5.25\n  final int decimalPrecision;\n\n  final bool showDivider;\n\n  final Color? activeColor;\n  final Color? inActiveColor;\n\n  const SliderSettingsTile({\n    super.key,\n    required this.title,\n    required this.settingKey,\n    required this.min,\n    required this.max,\n    this.subtitle = '',\n    this.defaultValue = 0.0,\n    this.enabled = true,\n    this.eagerUpdate = true,\n    this.step = 1.0,\n    this.onChange,\n    this.onChangeStart,\n    this.onChangeEnd,\n    this.leading,\n    this.decimalPrecision = 2,\n    this.titleTextStyle,\n    this.subtitleTextStyle,\n    this.activeColor,\n    this.inActiveColor,\n    this.showDivider = true,\n  });\n\n  @override\n  State<SliderSettingsTile> createState() => _SliderSettingsTileState();\n}\n\nclass _SliderSettingsTileState extends State<SliderSettingsTile> {\n  late double currentValue;\n\n  @override\n  void initState() {\n    currentValue = widget.defaultValue;\n    super.initState();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return ValueChangeObserver<double>(\n      cacheKey: widget.settingKey,\n      defaultValue: currentValue,\n      builder:\n          (BuildContext context, double value, OnChanged<double> onChanged) {\n        // debugPrint('creating settings Tile: ${widget.settingKey}');\n        return SettingsContainer(\n          children: <Widget>[\n            _SimpleHeaderTile(\n              title: widget.title,\n              subtitle: widget.subtitle.isNotEmpty\n                  ? widget.subtitle\n                  : value.toStringAsFixed(widget.decimalPrecision),\n              leading: widget.leading,\n              titleTextStyle: widget.titleTextStyle,\n              subtitleTextStyle: widget.subtitleTextStyle,\n            ),\n            _SettingsSlider(\n              onChanged: (newValue) =>\n                  _handleSliderChanged(newValue, onChanged),\n              onChangeStart: (newValue) =>\n                  _handleSliderChangeStart(newValue, onChanged),\n              onChangeEnd: (newValue) =>\n                  _handleSliderChangeEnd(newValue, onChanged),\n              enabled: widget.enabled,\n              eagerUpdate: widget.eagerUpdate,\n              value: value,\n              max: widget.max,\n              min: widget.min,\n              step: widget.step,\n              activeColor: widget.activeColor,\n              inActiveColor: widget.inActiveColor,\n            ),\n            if (widget.showDivider) _SettingsTileDivider(),\n          ],\n        );\n      },\n    );\n  }\n\n  void _updateWidget(double newValue, OnChanged<double> onChanged) {\n    currentValue = newValue;\n    onChanged(newValue);\n  }\n\n  void _handleSliderChanged(double newValue, OnChanged<double> onChanged) {\n    _updateWidget(newValue, onChanged);\n    widget.onChange?.call(newValue);\n  }\n\n  void _handleSliderChangeStart(double newValue, OnChanged<double> onChanged) {\n    _updateWidget(newValue, onChanged);\n    widget.onChangeStart?.call(newValue);\n  }\n\n  Future<void> _handleSliderChangeEnd(\n      double newValue, OnChanged<double> onChanged) async {\n    _updateWidget(newValue, onChanged);\n    widget.onChangeEnd?.call(newValue);\n  }\n}\n\n/// [ColorPickerSettingsTile] is a widget which allows user to\n/// select the a color from a set of Material color choices.\n///\n/// Since, [Color] is an in-memory object type, the serialized version\n/// of the value of this widget will be a Hex value [String] of the selected\n/// color.\n///\n/// This conversion string <-> color, makes this easy to check/debug the values\n/// from the storage/preference manually.\n///\n/// The color panel shown in the widget is provided by `flutter_material_color_picker` library.\n///\n/// Example:\n///\n/// ```dart\n///  ColorPickerSettingsTile(\n///    settingKey: 'key-color-picker',\n///    title: 'Accent Color',\n///    defaultValue: Colors.blue,\n///    onChange: (value) {\n///      debugPrint('key-color-picker: $value');\n///    },\n///  );\n/// ```\nclass ColorPickerSettingsTile extends StatefulWidget {\n  /// Settings Key string for storing the state of Color picker in cache (assumed to be unique)\n  final String settingKey;\n\n  /// Default value of the color as a Hex String, default = '#ff000000'\n  final String defaultStringValue;\n\n  /// Default value of the color\n  final Color? defaultValue;\n\n  /// title for the settings tile\n  final String title;\n\n  /// subtitle for the settings tile, default = ''\n  final String subtitle;\n\n  /// title text style\n  final TextStyle? titleTextStyle;\n\n  /// subtitle text style\n  final TextStyle? subtitleTextStyle;\n\n  /// The widget shown in front of the title\n  final Widget? leading;\n\n  /// flag which represents the state of the settings, if false the the tile will\n  /// ignore all the user inputs, default = true\n  final bool enabled;\n\n  /// on change callback for handling the value change\n  final OnChanged<Color>? onChange;\n\n  final bool showDivider;\n\n  const ColorPickerSettingsTile({\n    super.key,\n    required this.title,\n    required this.settingKey,\n    this.defaultValue,\n    this.enabled = true,\n    this.onChange,\n    this.defaultStringValue = '#ff000000',\n    this.subtitle = '',\n    this.leading,\n    this.titleTextStyle,\n    this.subtitleTextStyle,\n    this.showDivider = true,\n  });\n\n  @override\n  State<ColorPickerSettingsTile> createState() =>\n      _ColorPickerSettingsTileState();\n}\n\nclass _ColorPickerSettingsTileState extends State<ColorPickerSettingsTile> {\n  late String currentValue;\n\n  @override\n  void initState() {\n    super.initState();\n\n    if (widget.defaultValue != null) {\n      currentValue = ConversionUtils.stringFromColor(widget.defaultValue!);\n    } else {\n      currentValue = widget.defaultStringValue;\n    }\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return ValueChangeObserver<String>(\n      cacheKey: widget.settingKey,\n      defaultValue: currentValue,\n      builder:\n          (BuildContext context, String value, OnChanged<String> onChanged) {\n        // debugPrint('creating settings Tile: ${widget.settingKey}');\n        return _SettingsColorPicker(\n          title: widget.title,\n          value: value,\n          leading: widget.leading,\n          enabled: widget.enabled,\n          subtitle: widget.subtitle,\n          onChanged: (color) => _handleColorChanged(color, onChanged),\n          titleTextStyle: widget.titleTextStyle,\n          subtitleTextStyle: widget.subtitleTextStyle,\n          showDivider: widget.showDivider,\n        );\n      },\n    );\n  }\n\n  Future<void> _handleColorChanged(\n      String color, OnChanged<String> onChanged) async {\n    currentValue = color;\n    onChanged(color);\n    final colorFromString = ConversionUtils.colorFromString(color);\n    widget.onChange?.call(colorFromString);\n  }\n}\n\n/// [RadioModalSettingsTile] widget is the dialog version of the\n/// [RadioSettingsTile] widget.\n///\n/// Meaning this widget is similar to a [RadioSettingsTile] shown in a dialog.\n///\n/// Use of this widget is similar to the [RadioSettingsTile], only the displayed\n/// widget will be in a different position. i.e instead of the settings screen,\n/// it will be shown in a dialog above the settings screen.\n///\n/// Example:\n/// ```dart\n/// RadioModalSettingsTile<int>(\n///   title: 'Preferred Sync Period',\n///   settingKey: 'key-radio-sync-period',\n///   values: <int, String>{\n///     0: 'Never',\n///     1: 'Daily',\n///     7: 'Weekly',\n///     15: 'Fortnight',\n///     30: 'Monthly',\n///   },\n///   selected: 0,\n///   onChange: (value) {\n///     debugPrint('key-radio-sync-period: $value days');\n///   },\n/// );\n/// ```\n///\nclass RadioModalSettingsTile<T> extends StatefulWidget {\n  /// Settings Key string for storing the state of Radio setting in cache (assumed to be unique)\n  final String settingKey;\n\n  /// Selected value or group value of the radio buttons\n  final T selected;\n\n  /// A map containing unique values along with the display name\n  final Map<T, String> values;\n\n  /// title for the settings tile\n  final String title;\n\n  /// subtitle for the settings tile, default = ''\n  final String subtitle;\n\n  /// title text style\n  final TextStyle? titleTextStyle;\n\n  /// subtitle text style\n  final TextStyle? subtitleTextStyle;\n\n  /// The widget shown in front of the title\n  final Widget? leading;\n\n  /// flag which represents the state of the settings, if false the the tile will\n  /// ignore all the user inputs, default = true\n  final bool enabled;\n\n  /// flag which allows showing the display names along with the radio button\n  final bool showTitles;\n\n  /// on change callback for handling the value change\n  final OnChanged<T>? onChange;\n\n  final Color? activeColor;\n\n  final bool showDivider;\n\n  const RadioModalSettingsTile({\n    super.key,\n    required this.title,\n    required this.settingKey,\n    required this.selected,\n    required this.values,\n    this.enabled = true,\n    this.showTitles = false,\n    this.onChange,\n    this.subtitle = '',\n    this.leading,\n    this.titleTextStyle,\n    this.subtitleTextStyle,\n    this.activeColor,\n    this.showDivider = true,\n  });\n\n  @override\n  State<RadioModalSettingsTile<T>> createState() =>\n      _RadioModalSettingsTileState<T>();\n}\n\nclass _RadioModalSettingsTileState<T> extends State<RadioModalSettingsTile<T>> {\n  late T selectedValue;\n\n  @override\n  void initState() {\n    selectedValue = widget.selected;\n    super.initState();\n  }\n\n  Future<void> _onRadioChange(T? value, OnChanged<T> onChanged) async {\n    if (value == null) return;\n    selectedValue = value;\n    onChanged(value);\n    widget.onChange?.call(value);\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return ValueChangeObserver<T>(\n      cacheKey: widget.settingKey,\n      defaultValue: selectedValue,\n      builder: (BuildContext context, T value, OnChanged<T> onChanged) {\n        return SettingsContainer(\n          children: [\n            _ModalSettingsTile<T>(\n              title: widget.title,\n              subtitle: widget.subtitle.isNotEmpty\n                  ? widget.subtitle\n                  : widget.values[value],\n              leading: widget.leading,\n              titleTextStyle: widget.titleTextStyle,\n              subtitleTextStyle: widget.subtitleTextStyle,\n              children: <Widget>[\n                RadioSettingsTile<T>(\n                  title: '',\n                  showTitles: widget.showTitles,\n                  enabled: widget.enabled,\n                  values: widget.values,\n                  settingKey: widget.settingKey,\n                  onChange: (value) => _onRadioChange(value, onChanged),\n                  selected: value,\n                  activeColor: widget.activeColor,\n                  showDivider: widget.showDivider,\n                ),\n              ],\n            ),\n          ],\n        );\n      },\n    );\n  }\n}\n\n/// [SliderModalSettingsTile] widget is the dialog version of the\n/// [SliderSettingsTile] widget.\n///\n/// Meaning this widget is similar to a [SliderSettingsTile] shown in a dialog.\n///\n/// Use of this widget is similar to the [SliderSettingsTile], only the displayed\n/// widget will be in a different position. i.e instead of the settings screen,\n/// it will be shown in a dialog above the settings screen.\n///\n/// Example:\n/// ```dart\n/// SliderSettingsTile(\n///  title: 'Volume',\n///  settingKey: 'key-slider-volume',\n///  defaultValue: 20,\n///  min: 0,\n///  max: 100,\n///  step: 1,\n///  leading: Icon(Icons.volume_up),\n///  onChange: (value) {\n///    debugPrint('key-slider-volume: $value');\n///  },\n/// );\n/// ```\n///\nclass SliderModalSettingsTile extends StatefulWidget {\n  /// Settings Key string for storing the state of Slider in cache (assumed to be unique)\n  final String settingKey;\n\n  /// Selected value in the radio button group otherwise known as group value\n  /// default = 0.0\n  final double defaultValue;\n\n  /// title for the settings tile\n  final String title;\n\n  /// subtitle for the settings tile, default = ''\n  final String subtitle;\n\n  /// title text style\n  final TextStyle? titleTextStyle;\n\n  /// subtitle text style\n  final TextStyle? subtitleTextStyle;\n\n  /// The widget shown in front of the title\n  final Widget? leading;\n\n  /// flag which represents the state of the settings, if false the the tile will\n  /// ignore all the user inputs, default = true\n  final bool enabled;\n\n  /// flag which allows updating the value of setting immediately when the\n  /// slider is moved, default = true\n  ///\n  /// If this flag is enabled then [onChangeStart] & [onChangeEnd] callbacks are\n  /// ignored & will not be executed\n  ///\n  final bool eagerUpdate;\n\n  /// minimum allowed value for the slider, in other terms a start value\n  /// for the slider\n  final double min;\n\n  /// maximum allowed value for the slider, in other terms a end value\n  /// for the slider\n  final double max;\n\n  /// a step value which will be used to move the slider.\n  /// default = 1.0\n  ///\n  /// i.e. if the step = 1.0 then moving slider from left to right\n  /// will result in following values in order:\n  ///  1.0, 2.0, 3.0, 4.0, ..., 100.0\n  ///\n  /// if the step = 5.0 then the same slider movement will result in:\n  ///  5.0, 10.0, 15.0, 20.0, ..., 100.0\n  final double step;\n\n  /// on change callback for handling the value change\n  final OnChanged<double>? onChange;\n\n  /// callback for fetching the value slider movement starts\n  final OnChanged<double>? onChangeStart;\n\n  /// callback for fetching the value slider movement ends\n  final OnChanged<double>? onChangeEnd;\n\n  final Color? activeColor;\n  final Color? inActiveColor;\n\n  const SliderModalSettingsTile({\n    super.key,\n    required this.title,\n    required this.settingKey,\n    required this.min,\n    required this.max,\n    this.defaultValue = 0.0,\n    this.enabled = true,\n    this.step = 0.0,\n    this.onChange,\n    this.onChangeStart,\n    this.onChangeEnd,\n    this.subtitle = '',\n    this.leading,\n    this.eagerUpdate = true,\n    this.titleTextStyle,\n    this.subtitleTextStyle,\n    this.activeColor,\n    this.inActiveColor,\n  });\n\n  @override\n  State<SliderModalSettingsTile> createState() =>\n      _SliderModalSettingsTileState();\n}\n\nclass _SliderModalSettingsTileState extends State<SliderModalSettingsTile> {\n  late double currentValue;\n\n  @override\n  void initState() {\n    currentValue = widget.defaultValue;\n    super.initState();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return ValueChangeObserver<double>(\n      cacheKey: widget.settingKey,\n      defaultValue: currentValue,\n      builder:\n          (BuildContext context, double value, OnChanged<double> onChanged) {\n        // debugPrint('creating settings Tile: ${widget.settingKey}');\n        return SettingsContainer(\n          children: <Widget>[\n            _ModalSettingsTile<double>(\n              title: widget.title,\n              subtitle: widget.subtitle.isNotEmpty\n                  ? widget.subtitle\n                  : value.toString(),\n              leading: widget.leading,\n              titleTextStyle: widget.titleTextStyle,\n              subtitleTextStyle: widget.subtitleTextStyle,\n              children: <Widget>[\n                _SettingsSlider(\n                  onChanged: (double newValue) =>\n                      _handleSliderChanged(newValue, onChanged),\n                  onChangeStart: (double newValue) =>\n                      _handleSliderChangeStart(newValue, onChanged),\n                  onChangeEnd: (double newValue) =>\n                      _handleSliderChangeEnd(newValue, onChanged),\n                  enabled: widget.enabled,\n                  eagerUpdate: widget.eagerUpdate,\n                  value: value,\n                  max: widget.max,\n                  min: widget.min,\n                  step: widget.step,\n                  activeColor: widget.activeColor,\n                  inActiveColor: widget.inActiveColor,\n                )\n              ],\n            ),\n          ],\n        );\n      },\n    );\n  }\n\n  void _handleSliderChanged(double newValue, OnChanged<double> onChanged) {\n    _updateWidget(newValue, onChanged);\n    widget.onChange?.call(newValue);\n  }\n\n  void _handleSliderChangeStart(double newValue, OnChanged<double> onChanged) {\n    _updateWidget(newValue, onChanged);\n    widget.onChangeStart?.call(newValue);\n  }\n\n  void _handleSliderChangeEnd(double newValue, OnChanged<double> onChanged) {\n    _updateWidget(newValue, onChanged);\n    widget.onChangeEnd?.call(newValue);\n  }\n\n  void _updateWidget(double newValue, OnChanged<double> onChanged) {\n    currentValue = newValue;\n    onChanged(newValue);\n  }\n}\n\n/// [SimpleRadioSettingsTile] is a simpler version of\n/// the [RadioSettingsTile].\n///\n/// Instead of a Value-String map, this widget just takes a list\n/// of String values.\n///\n/// Example:\n/// ```dart\n/// SimpleRadioSettingsTile(\n///   title: 'Sync Settings',\n///   settingKey: 'key-radio-sync-settings',\n///   values: <String>[\n///     'Never',\n///     'Daily',\n///     'Weekly',\n///     'Fortnight',\n///     'Monthly',\n///   ],\n///   selected: 'Daily',\n///   onChange: (value) {\n///     debugPrint('key-radio-sync-settings: $value');\n///   },\n/// );\n/// ```\nclass SimpleRadioSettingsTile extends StatelessWidget {\n  /// Settings Key string for storing the state of Radio setting in cache (assumed to be unique)\n  final String settingKey;\n\n  /// Selected value or group value of the radio buttons\n  final String selected;\n\n  /// A map containing unique values along with the display name\n  final List<String> values;\n\n  /// title for the settings tile\n  final String title;\n\n  /// subtitle for the settings tile, default = ''\n  final String subtitle;\n\n  /// title text style\n  final TextStyle? titleTextStyle;\n\n  /// subtitle text style\n  final TextStyle? subtitleTextStyle;\n\n  /// The widget shown in front of the title\n  final Widget? leading;\n\n  /// flag which represents the state of the settings, if false the the tile will\n  /// ignore all the user inputs, default = true\n  final bool enabled;\n\n  /// on change callback for handling the value change\n  final OnChanged<String>? onChange;\n\n  const SimpleRadioSettingsTile({\n    super.key,\n    required this.title,\n    required this.settingKey,\n    required this.selected,\n    required this.values,\n    this.enabled = true,\n    this.onChange,\n    this.subtitle = '',\n    this.leading,\n    this.titleTextStyle,\n    this.subtitleTextStyle,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return RadioSettingsTile<String>(\n      title: title,\n      subtitle: subtitle,\n      leading: leading,\n      settingKey: settingKey,\n      selected: selected,\n      enabled: enabled,\n      onChange: onChange,\n      values: getValues(values),\n      titleTextStyle: titleTextStyle,\n      subtitleTextStyle: subtitleTextStyle,\n    );\n  }\n\n  Map<String, String> getValues(List<String> values) {\n    final valueMap = <String, String>{};\n    for (var value in values) {\n      valueMap[value] = value;\n    }\n    return valueMap;\n  }\n}\n\n/// [SimpleDropDownSettingsTile] is a simpler version of\n/// the [DropDownSettingsTile].\n///\n/// Instead of a Value-String map, this widget just takes a list\n/// of String values.\n///\n/// Example:\n/// ```dart\n/// SimpleDropDownSettingsTile(\n///   title: 'Beauty Filter',\n///   settingKey: 'key-dropdown-beauty-filter',\n///   values: <String>[\n///     'Simple',\n///     'Normal',\n///     'Little Special',\n///     'Special',\n///     'Extra Special',\n///     'Bizzar',\n///     'Horrific',\n///   ],\n///   selected: 'Special',\n///   onChange: (value) {\n///     debugPrint('key-dropdown-beauty-filter: $value');\n///  },\n/// );\n/// ```\nclass SimpleDropDownSettingsTile extends StatelessWidget {\n  /// Settings Key string for storing the state of Radio buttons in cache (assumed to be unique)\n  final String settingKey;\n\n  /// Selected value in the radio button group otherwise known as group value\n  final String selected;\n\n  /// A map containing unique values along with the display name\n  final List<String> values;\n\n  /// title for the settings tile\n  final String title;\n\n  /// subtitle for the settings tile, default = ''\n  final String subtitle;\n\n  /// title text style\n  final TextStyle? titleTextStyle;\n\n  /// subtitle text style\n  final TextStyle? subtitleTextStyle;\n\n  /// The widget shown in front of the title\n  final Widget? leading;\n\n  /// flag which represents the state of the settings, if false the the tile will\n  /// ignore all the user inputs, default = true\n  final bool enabled;\n\n  /// on change callback for handling the value change\n  final OnChanged<String>? onChange;\n\n  const SimpleDropDownSettingsTile({\n    super.key,\n    required this.title,\n    required this.settingKey,\n    required this.selected,\n    required this.values,\n    this.enabled = true,\n    this.onChange,\n    this.subtitle = '',\n    this.leading,\n    this.titleTextStyle,\n    this.subtitleTextStyle,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return DropDownSettingsTile<String>(\n      title: title,\n      subtitle: subtitle,\n      leading: leading,\n      settingKey: settingKey,\n      selected: selected,\n      enabled: enabled,\n      onChange: onChange,\n      values: getValues(values),\n      titleTextStyle: titleTextStyle,\n      subtitleTextStyle: subtitleTextStyle,\n    );\n  }\n\n  Map<String, String> getValues(List<String> values) {\n    final valueMap = <String, String>{};\n    for (var value in values) {\n      valueMap[value] = value;\n    }\n    return valueMap;\n  }\n}\n"
  },
  {
    "path": "pubspec.yaml",
    "content": "name: flutter_settings_screens\ndescription: A Simple plugin to implement settings UI screens for your flutter apps. Customize what you want, From UI elements, behaviour or underlying storage library.\nrepository: https://github.com/GAM3RG33K/flutter_settings_screens\nhomepage: https://github.com/GAM3RG33K/flutter_settings_screens\nversion: 0.3.4\n\nenvironment:\n  sdk: '>=3.2.4 <4.0.0'\n\ndependencies:\n  flutter:\n    sdk: flutter\n\n  # library to access storage directories\n  path_provider: ^2.0.10\n\n  # library to use Provider widgets\n  provider: ^6.0.3\n\n  # library to store the preference/settings using shared_preferences library\n  shared_preferences: ^2.0.15\n\ndev_dependencies:\n  flutter_test:\n    sdk: flutter\n\n  # to enforce dart coding standard\n  flutter_lints: ^3.0.0\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"
  },
  {
    "path": "test/flutter_settings_screens_test.dart",
    "content": "//import 'package:flutter/services.dart';\n//import 'package:flutter_test/flutter_test.dart';\n//import 'package:flutter_settings_screens/flutter_settings_screens.dart';\n//\n//void main() {\n//  const MethodChannel channel = MethodChannel('flutter_settings_screens');\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//  test('getPlatformVersion', () async {\n//    expect(await FlutterSettingsScreens.platformVersion, '42');\n//  });\n//}\n"
  }
]