feat: Implémentation authentification NIST SP 800-63B v3.0.8
- Ajout du service PasswordSecurityService conforme NIST SP 800-63B - Vérification des mots de passe contre la base Have I Been Pwned - Validation : minimum 8 caractères, maximum 64 caractères - Pas d'exigences de composition obligatoires (conforme NIST) - Intégration dans LoginController et UserController - Génération de mots de passe sécurisés non compromis 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -79,9 +79,9 @@ file:///home/pierre/.pub-cache/hosted/pub.dev/collection-1.19.1/lib/src/union_se
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/collection-1.19.1/lib/src/unmodifiable_wrappers.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/collection-1.19.1/lib/src/utils.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/collection-1.19.1/lib/src/wrappers.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.4/lib/connectivity_plus.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.4/lib/src/connectivity_plus_web.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.4/lib/src/web/dart_html_connectivity_plugin.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/lib/connectivity_plus.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/lib/src/connectivity_plus_web.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/lib/src/web/dart_html_connectivity_plugin.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus_platform_interface-2.0.1/lib/connectivity_plus_platform_interface.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus_platform_interface-2.0.1/lib/method_channel_connectivity.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus_platform_interface-2.0.1/lib/src/enums.dart
|
||||
@@ -507,23 +507,24 @@ file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_for_web-3.0.6/lib/ima
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_for_web-3.0.6/lib/src/image_resizer.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_for_web-3.0.6/lib/src/image_resizer_utils.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_for_web-3.0.6/lib/src/pkg_web_tweaks.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/image_picker_platform_interface.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/method_channel/method_channel_image_picker.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/platform_interface/image_picker_platform.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/camera_delegate.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/camera_device.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/image_options.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/image_source.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/lost_data_response.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/media_options.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/media_selection_type.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/multi_image_picker_options.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/picked_file/base.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/picked_file/html.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/picked_file/lost_data.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/picked_file/picked_file.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/retrieve_type.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/types.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/image_picker_platform_interface.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/method_channel/method_channel_image_picker.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/platform_interface/image_picker_platform.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/camera_delegate.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/camera_device.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/image_options.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/image_source.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/lost_data_response.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/media_options.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/media_selection_type.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/multi_image_picker_options.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/multi_video_picker_options.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/picked_file/base.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/picked_file/html.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/picked_file/lost_data.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/picked_file/picked_file.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/retrieve_type.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/types.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/intl-0.20.2/lib/date_symbol_data_custom.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/intl-0.20.2/lib/date_symbols.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/intl-0.20.2/lib/intl.dart
|
||||
@@ -652,12 +653,12 @@ file:///home/pierre/.pub-cache/hosted/pub.dev/mime-2.0.0/lib/src/magic_number.da
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/mime-2.0.0/lib/src/mime_multipart_transformer.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/mime-2.0.0/lib/src/mime_shared.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/mime-2.0.0/lib/src/mime_type.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus-8.3.0/lib/package_info_plus.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus-8.3.0/lib/src/package_info_plus_linux.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus-8.3.0/lib/src/package_info_plus_web.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus_platform_interface-3.2.0/lib/method_channel_package_info.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus_platform_interface-3.2.0/lib/package_info_data.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus_platform_interface-3.2.0/lib/package_info_platform_interface.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/lib/package_info_plus.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/lib/src/package_info_plus_linux.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/lib/src/package_info_plus_web.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus_platform_interface-3.2.1/lib/method_channel_package_info.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus_platform_interface-3.2.1/lib/package_info_data.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus_platform_interface-3.2.1/lib/package_info_platform_interface.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/path-1.9.1/lib/path.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/path-1.9.1/lib/src/characters.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/path-1.9.1/lib/src/context.dart
|
||||
@@ -773,128 +774,128 @@ file:///home/pierre/.pub-cache/hosted/pub.dev/string_scanner-1.4.1/lib/src/span_
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/string_scanner-1.4.1/lib/src/string_scanner.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/string_scanner-1.4.1/lib/src/utils.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/string_scanner-1.4.1/lib/string_scanner.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/charts.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/axis/axis.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/axis/category_axis.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/axis/datetime_axis.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/axis/datetime_category_axis.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/axis/logarithmic_axis.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/axis/multi_level_labels.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/axis/numeric_axis.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/axis/plot_band.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/base.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/behaviors/crosshair.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/behaviors/trackball.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/behaviors/zooming.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/cartesian_chart.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/circular_chart.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/annotation.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/callbacks.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/chart_point.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/circular_data_label.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/circular_data_label_helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/connector_line.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/core_legend.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/core_tooltip.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/data_label.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/element_widget.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/empty_points.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/funnel_data_label.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/interactive_tooltip.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/layout_handler.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/legend.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/marker.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/pyramid_data_label.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/title.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/funnel_chart.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/accumulation_distribution_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/atr_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/bollinger_bands_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/ema_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/macd_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/momentum_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/roc_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/rsi_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/sma_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/stochastic_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/technical_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/tma_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/wma_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/interactions/behavior.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/interactions/selection.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/interactions/tooltip.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/pyramid_chart.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/area_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/bar_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/box_and_whisker_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/bubble_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/candle_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/chart_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/column_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/doughnut_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/error_bar_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/fast_line_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/funnel_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/hilo_open_close_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/hilo_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/histogram_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/line_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/pie_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/pyramid_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/radial_bar_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/range_area_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/range_column_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/scatter_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/spline_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/stacked_area100_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/stacked_area_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/stacked_bar100_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/stacked_bar_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/stacked_column100_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/stacked_column_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/stacked_line100_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/stacked_line_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/step_area_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/stepline_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/waterfall_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/trendline/trendline.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/utils/constants.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/utils/enum.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/utils/helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/utils/renderer_helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/utils/typedef.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/utils/zooming_helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/sparkline/marker.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/sparkline/utils/enum.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/sparkline/utils/helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/core.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/localizations.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/calendar/calendar_helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/calendar/hijri_date_time.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/localizations/global_localizations.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/slider_controller.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/assistview_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/barcodes_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/calendar_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/charts_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/chat_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/color_scheme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/datagrid_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/datapager_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/daterangepicker_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/gauges_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/maps_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/pdfviewer_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/range_selector_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/range_slider_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/slider_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/spark_charts_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/theme_widget.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/treemap_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/utils/helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/utils/shape_helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/charts.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/axis/axis.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/axis/category_axis.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/axis/datetime_axis.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/axis/datetime_category_axis.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/axis/logarithmic_axis.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/axis/multi_level_labels.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/axis/numeric_axis.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/axis/plot_band.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/base.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/behaviors/crosshair.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/behaviors/trackball.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/behaviors/zooming.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/cartesian_chart.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/circular_chart.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/annotation.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/callbacks.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/chart_point.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/circular_data_label.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/circular_data_label_helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/connector_line.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/core_legend.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/core_tooltip.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/data_label.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/element_widget.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/empty_points.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/funnel_data_label.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/interactive_tooltip.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/layout_handler.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/legend.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/marker.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/pyramid_data_label.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/title.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/funnel_chart.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/accumulation_distribution_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/atr_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/bollinger_bands_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/ema_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/macd_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/momentum_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/roc_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/rsi_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/sma_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/stochastic_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/technical_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/tma_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/wma_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/interactions/behavior.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/interactions/selection.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/interactions/tooltip.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/pyramid_chart.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/area_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/bar_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/box_and_whisker_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/bubble_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/candle_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/chart_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/column_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/doughnut_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/error_bar_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/fast_line_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/funnel_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/hilo_open_close_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/hilo_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/histogram_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/line_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/pie_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/pyramid_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/radial_bar_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/range_area_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/range_column_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/scatter_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/spline_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/stacked_area100_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/stacked_area_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/stacked_bar100_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/stacked_bar_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/stacked_column100_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/stacked_column_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/stacked_line100_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/stacked_line_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/step_area_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/stepline_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/waterfall_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/trendline/trendline.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/utils/constants.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/utils/enum.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/utils/helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/utils/renderer_helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/utils/typedef.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/utils/zooming_helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/sparkline/marker.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/sparkline/utils/enum.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/sparkline/utils/helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/core.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/localizations.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/calendar/calendar_helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/calendar/hijri_date_time.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/localizations/global_localizations.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/slider_controller.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/assistview_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/barcodes_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/calendar_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/charts_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/chat_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/color_scheme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/datagrid_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/datapager_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/daterangepicker_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/gauges_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/maps_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/pdfviewer_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/range_selector_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/range_slider_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/slider_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/spark_charts_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/theme_widget.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/treemap_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/utils/helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/utils/shape_helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/term_glyph-1.2.2/lib/src/generated/ascii_glyph_set.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/term_glyph-1.2.2/lib/src/generated/glyph_set.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/term_glyph-1.2.2/lib/src/generated/top_level.dart
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -79,9 +79,9 @@ file:///home/pierre/.pub-cache/hosted/pub.dev/collection-1.19.1/lib/src/union_se
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/collection-1.19.1/lib/src/unmodifiable_wrappers.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/collection-1.19.1/lib/src/utils.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/collection-1.19.1/lib/src/wrappers.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.4/lib/connectivity_plus.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.4/lib/src/connectivity_plus_web.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.4/lib/src/web/dart_html_connectivity_plugin.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/lib/connectivity_plus.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/lib/src/connectivity_plus_web.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/lib/src/web/dart_html_connectivity_plugin.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus_platform_interface-2.0.1/lib/connectivity_plus_platform_interface.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus_platform_interface-2.0.1/lib/method_channel_connectivity.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus_platform_interface-2.0.1/lib/src/enums.dart
|
||||
@@ -507,23 +507,24 @@ file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_for_web-3.0.6/lib/ima
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_for_web-3.0.6/lib/src/image_resizer.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_for_web-3.0.6/lib/src/image_resizer_utils.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_for_web-3.0.6/lib/src/pkg_web_tweaks.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/image_picker_platform_interface.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/method_channel/method_channel_image_picker.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/platform_interface/image_picker_platform.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/camera_delegate.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/camera_device.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/image_options.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/image_source.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/lost_data_response.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/media_options.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/media_selection_type.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/multi_image_picker_options.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/picked_file/base.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/picked_file/html.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/picked_file/lost_data.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/picked_file/picked_file.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/retrieve_type.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/src/types/types.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/image_picker_platform_interface.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/method_channel/method_channel_image_picker.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/platform_interface/image_picker_platform.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/camera_delegate.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/camera_device.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/image_options.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/image_source.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/lost_data_response.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/media_options.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/media_selection_type.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/multi_image_picker_options.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/multi_video_picker_options.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/picked_file/base.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/picked_file/html.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/picked_file/lost_data.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/picked_file/picked_file.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/retrieve_type.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/src/types/types.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/intl-0.20.2/lib/date_symbol_data_custom.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/intl-0.20.2/lib/date_symbols.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/intl-0.20.2/lib/intl.dart
|
||||
@@ -652,12 +653,12 @@ file:///home/pierre/.pub-cache/hosted/pub.dev/mime-2.0.0/lib/src/magic_number.da
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/mime-2.0.0/lib/src/mime_multipart_transformer.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/mime-2.0.0/lib/src/mime_shared.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/mime-2.0.0/lib/src/mime_type.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus-8.3.0/lib/package_info_plus.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus-8.3.0/lib/src/package_info_plus_linux.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus-8.3.0/lib/src/package_info_plus_web.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus_platform_interface-3.2.0/lib/method_channel_package_info.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus_platform_interface-3.2.0/lib/package_info_data.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus_platform_interface-3.2.0/lib/package_info_platform_interface.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/lib/package_info_plus.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/lib/src/package_info_plus_linux.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/lib/src/package_info_plus_web.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus_platform_interface-3.2.1/lib/method_channel_package_info.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus_platform_interface-3.2.1/lib/package_info_data.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus_platform_interface-3.2.1/lib/package_info_platform_interface.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/path-1.9.1/lib/path.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/path-1.9.1/lib/src/characters.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/path-1.9.1/lib/src/context.dart
|
||||
@@ -773,128 +774,128 @@ file:///home/pierre/.pub-cache/hosted/pub.dev/string_scanner-1.4.1/lib/src/span_
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/string_scanner-1.4.1/lib/src/string_scanner.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/string_scanner-1.4.1/lib/src/utils.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/string_scanner-1.4.1/lib/string_scanner.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/charts.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/axis/axis.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/axis/category_axis.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/axis/datetime_axis.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/axis/datetime_category_axis.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/axis/logarithmic_axis.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/axis/multi_level_labels.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/axis/numeric_axis.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/axis/plot_band.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/base.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/behaviors/crosshair.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/behaviors/trackball.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/behaviors/zooming.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/cartesian_chart.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/circular_chart.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/annotation.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/callbacks.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/chart_point.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/circular_data_label.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/circular_data_label_helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/connector_line.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/core_legend.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/core_tooltip.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/data_label.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/element_widget.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/empty_points.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/funnel_data_label.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/interactive_tooltip.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/layout_handler.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/legend.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/marker.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/pyramid_data_label.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/common/title.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/funnel_chart.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/accumulation_distribution_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/atr_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/bollinger_bands_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/ema_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/macd_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/momentum_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/roc_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/rsi_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/sma_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/stochastic_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/technical_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/tma_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/indicators/wma_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/interactions/behavior.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/interactions/selection.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/interactions/tooltip.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/pyramid_chart.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/area_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/bar_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/box_and_whisker_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/bubble_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/candle_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/chart_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/column_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/doughnut_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/error_bar_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/fast_line_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/funnel_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/hilo_open_close_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/hilo_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/histogram_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/line_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/pie_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/pyramid_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/radial_bar_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/range_area_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/range_column_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/scatter_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/spline_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/stacked_area100_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/stacked_area_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/stacked_bar100_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/stacked_bar_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/stacked_column100_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/stacked_column_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/stacked_line100_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/stacked_line_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/step_area_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/stepline_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/series/waterfall_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/trendline/trendline.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/utils/constants.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/utils/enum.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/utils/helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/utils/renderer_helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/utils/typedef.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/charts/utils/zooming_helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/sparkline/marker.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/sparkline/utils/enum.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/src/sparkline/utils/helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/core.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/localizations.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/calendar/calendar_helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/calendar/hijri_date_time.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/localizations/global_localizations.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/slider_controller.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/assistview_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/barcodes_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/calendar_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/charts_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/chat_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/color_scheme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/datagrid_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/datapager_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/daterangepicker_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/gauges_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/maps_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/pdfviewer_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/range_selector_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/range_slider_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/slider_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/spark_charts_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/theme_widget.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/theme/treemap_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/utils/helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/src/utils/shape_helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/charts.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/axis/axis.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/axis/category_axis.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/axis/datetime_axis.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/axis/datetime_category_axis.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/axis/logarithmic_axis.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/axis/multi_level_labels.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/axis/numeric_axis.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/axis/plot_band.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/base.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/behaviors/crosshair.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/behaviors/trackball.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/behaviors/zooming.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/cartesian_chart.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/circular_chart.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/annotation.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/callbacks.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/chart_point.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/circular_data_label.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/circular_data_label_helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/connector_line.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/core_legend.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/core_tooltip.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/data_label.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/element_widget.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/empty_points.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/funnel_data_label.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/interactive_tooltip.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/layout_handler.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/legend.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/marker.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/pyramid_data_label.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/common/title.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/funnel_chart.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/accumulation_distribution_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/atr_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/bollinger_bands_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/ema_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/macd_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/momentum_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/roc_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/rsi_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/sma_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/stochastic_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/technical_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/tma_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/indicators/wma_indicator.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/interactions/behavior.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/interactions/selection.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/interactions/tooltip.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/pyramid_chart.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/area_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/bar_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/box_and_whisker_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/bubble_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/candle_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/chart_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/column_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/doughnut_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/error_bar_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/fast_line_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/funnel_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/hilo_open_close_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/hilo_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/histogram_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/line_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/pie_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/pyramid_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/radial_bar_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/range_area_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/range_column_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/scatter_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/spline_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/stacked_area100_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/stacked_area_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/stacked_bar100_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/stacked_bar_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/stacked_column100_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/stacked_column_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/stacked_line100_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/stacked_line_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/step_area_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/stepline_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/series/waterfall_series.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/trendline/trendline.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/utils/constants.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/utils/enum.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/utils/helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/utils/renderer_helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/utils/typedef.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/charts/utils/zooming_helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/sparkline/marker.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/sparkline/utils/enum.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/src/sparkline/utils/helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/core.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/localizations.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/calendar/calendar_helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/calendar/hijri_date_time.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/localizations/global_localizations.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/slider_controller.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/assistview_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/barcodes_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/calendar_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/charts_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/chat_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/color_scheme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/datagrid_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/datapager_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/daterangepicker_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/gauges_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/maps_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/pdfviewer_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/range_selector_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/range_slider_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/slider_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/spark_charts_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/theme_widget.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/theme/treemap_theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/utils/helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/src/utils/shape_helper.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/theme.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/term_glyph-1.2.2/lib/src/generated/ascii_glyph_set.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/term_glyph-1.2.2/lib/src/generated/glyph_set.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/term_glyph-1.2.2/lib/src/generated/top_level.dart
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -135,7 +135,7 @@
|
||||
},
|
||||
{
|
||||
"name": "connectivity_plus",
|
||||
"rootUri": "file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.4",
|
||||
"rootUri": "file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.2"
|
||||
},
|
||||
@@ -549,9 +549,9 @@
|
||||
},
|
||||
{
|
||||
"name": "image_picker_platform_interface",
|
||||
"rootUri": "file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1",
|
||||
"rootUri": "file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.4"
|
||||
"languageVersion": "3.6"
|
||||
},
|
||||
{
|
||||
"name": "image_picker_windows",
|
||||
@@ -669,7 +669,7 @@
|
||||
},
|
||||
{
|
||||
"name": "mqtt5_client",
|
||||
"rootUri": "file:///home/pierre/.pub-cache/hosted/pub.dev/mqtt5_client-4.13.3",
|
||||
"rootUri": "file:///home/pierre/.pub-cache/hosted/pub.dev/mqtt5_client-4.14.0",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.8"
|
||||
},
|
||||
@@ -687,13 +687,13 @@
|
||||
},
|
||||
{
|
||||
"name": "package_info_plus",
|
||||
"rootUri": "file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus-8.3.0",
|
||||
"rootUri": "file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.3"
|
||||
},
|
||||
{
|
||||
"name": "package_info_plus_platform_interface",
|
||||
"rootUri": "file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus_platform_interface-3.2.0",
|
||||
"rootUri": "file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus_platform_interface-3.2.1",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "2.18"
|
||||
},
|
||||
@@ -909,13 +909,13 @@
|
||||
},
|
||||
{
|
||||
"name": "syncfusion_flutter_charts",
|
||||
"rootUri": "file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4",
|
||||
"rootUri": "file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.7"
|
||||
},
|
||||
{
|
||||
"name": "syncfusion_flutter_core",
|
||||
"rootUri": "file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4",
|
||||
"rootUri": "file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.7"
|
||||
},
|
||||
|
||||
@@ -84,8 +84,8 @@ file:///home/pierre/.pub-cache/hosted/pub.dev/collection-1.19.1/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/collection-1.19.1/lib/
|
||||
connectivity_plus
|
||||
3.2
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.4/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.4/lib/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/lib/
|
||||
connectivity_plus_platform_interface
|
||||
2.18
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus_platform_interface-2.0.1/
|
||||
@@ -343,9 +343,9 @@ image_picker_macos
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_macos-0.2.1+2/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_macos-0.2.1+2/lib/
|
||||
image_picker_platform_interface
|
||||
3.4
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.10.1/lib/
|
||||
3.6
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.11.0/lib/
|
||||
image_picker_windows
|
||||
2.19
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/image_picker_windows-0.2.1+1/
|
||||
@@ -424,8 +424,8 @@ file:///home/pierre/.pub-cache/hosted/pub.dev/mime-2.0.0/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/mime-2.0.0/lib/
|
||||
mqtt5_client
|
||||
3.8
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/mqtt5_client-4.13.3/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/mqtt5_client-4.13.3/lib/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/mqtt5_client-4.14.0/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/mqtt5_client-4.14.0/lib/
|
||||
nm
|
||||
2.12
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/nm-0.5.0/
|
||||
@@ -436,12 +436,12 @@ file:///home/pierre/.pub-cache/hosted/pub.dev/package_config-2.2.0/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_config-2.2.0/lib/
|
||||
package_info_plus
|
||||
3.3
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus-8.3.0/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus-8.3.0/lib/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/lib/
|
||||
package_info_plus_platform_interface
|
||||
2.18
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus_platform_interface-3.2.0/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus_platform_interface-3.2.0/lib/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus_platform_interface-3.2.1/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/package_info_plus_platform_interface-3.2.1/lib/
|
||||
path
|
||||
3.4
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/path-1.9.1/
|
||||
@@ -580,12 +580,12 @@ file:///home/pierre/.pub-cache/hosted/pub.dev/string_scanner-1.4.1/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/string_scanner-1.4.1/lib/
|
||||
syncfusion_flutter_charts
|
||||
3.7
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.4/lib/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_charts-30.2.5/lib/
|
||||
syncfusion_flutter_core
|
||||
3.7
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.4/lib/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/syncfusion_flutter_core-30.2.5/lib/
|
||||
synchronized
|
||||
3.8
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/synchronized-3.4.0/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"packages": [
|
||||
{
|
||||
"name": "geosector_app",
|
||||
"version": "3.0.6+306",
|
||||
"version": "3.0.8+308",
|
||||
"dependencies": [
|
||||
"connectivity_plus",
|
||||
"cupertino_icons",
|
||||
@@ -170,22 +170,6 @@
|
||||
"path"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "package_info_plus",
|
||||
"version": "8.3.0",
|
||||
"dependencies": [
|
||||
"clock",
|
||||
"ffi",
|
||||
"flutter",
|
||||
"flutter_web_plugins",
|
||||
"http",
|
||||
"meta",
|
||||
"package_info_plus_platform_interface",
|
||||
"path",
|
||||
"web",
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "retry",
|
||||
"version": "3.1.2",
|
||||
@@ -435,27 +419,6 @@
|
||||
"meta"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "package_info_plus_platform_interface",
|
||||
"version": "3.2.0",
|
||||
"dependencies": [
|
||||
"flutter",
|
||||
"meta",
|
||||
"plugin_platform_interface"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "flutter_web_plugins",
|
||||
"version": "0.0.0",
|
||||
"dependencies": [
|
||||
"characters",
|
||||
"collection",
|
||||
"flutter",
|
||||
"material_color_utilities",
|
||||
"meta",
|
||||
"vector_math"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "sky_engine",
|
||||
"version": "0.0.0",
|
||||
@@ -503,52 +466,42 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "syncfusion_flutter_charts",
|
||||
"version": "30.2.4",
|
||||
"name": "package_info_plus",
|
||||
"version": "8.3.1",
|
||||
"dependencies": [
|
||||
"flutter",
|
||||
"intl",
|
||||
"syncfusion_flutter_core",
|
||||
"vector_math"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "syncfusion_flutter_core",
|
||||
"version": "30.2.4",
|
||||
"dependencies": [
|
||||
"flutter",
|
||||
"vector_math"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "connectivity_plus",
|
||||
"version": "6.1.4",
|
||||
"dependencies": [
|
||||
"collection",
|
||||
"connectivity_plus_platform_interface",
|
||||
"clock",
|
||||
"ffi",
|
||||
"flutter",
|
||||
"flutter_web_plugins",
|
||||
"http",
|
||||
"meta",
|
||||
"nm",
|
||||
"web"
|
||||
"package_info_plus_platform_interface",
|
||||
"path",
|
||||
"web",
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "nm",
|
||||
"version": "0.5.0",
|
||||
"dependencies": [
|
||||
"dbus"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "connectivity_plus_platform_interface",
|
||||
"version": "2.0.1",
|
||||
"name": "package_info_plus_platform_interface",
|
||||
"version": "3.2.1",
|
||||
"dependencies": [
|
||||
"flutter",
|
||||
"meta",
|
||||
"plugin_platform_interface"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "flutter_web_plugins",
|
||||
"version": "0.0.0",
|
||||
"dependencies": [
|
||||
"characters",
|
||||
"collection",
|
||||
"flutter",
|
||||
"material_color_utilities",
|
||||
"meta",
|
||||
"vector_math"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "go_router",
|
||||
"version": "16.1.0",
|
||||
@@ -601,16 +554,6 @@
|
||||
"image_picker_platform_interface"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "image_picker_platform_interface",
|
||||
"version": "2.10.1",
|
||||
"dependencies": [
|
||||
"cross_file",
|
||||
"flutter",
|
||||
"http",
|
||||
"plugin_platform_interface"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "typed_data",
|
||||
"version": "1.4.0",
|
||||
@@ -618,13 +561,6 @@
|
||||
"collection"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "plugin_platform_interface",
|
||||
"version": "2.1.8",
|
||||
"dependencies": [
|
||||
"meta"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "http_cache_core",
|
||||
"version": "1.1.1",
|
||||
@@ -744,11 +680,75 @@
|
||||
"meta"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "syncfusion_flutter_charts",
|
||||
"version": "30.2.5",
|
||||
"dependencies": [
|
||||
"flutter",
|
||||
"intl",
|
||||
"syncfusion_flutter_core",
|
||||
"vector_math"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "syncfusion_flutter_core",
|
||||
"version": "30.2.5",
|
||||
"dependencies": [
|
||||
"flutter",
|
||||
"vector_math"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "connectivity_plus",
|
||||
"version": "6.1.5",
|
||||
"dependencies": [
|
||||
"collection",
|
||||
"connectivity_plus_platform_interface",
|
||||
"flutter",
|
||||
"flutter_web_plugins",
|
||||
"meta",
|
||||
"nm",
|
||||
"web"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "nm",
|
||||
"version": "0.5.0",
|
||||
"dependencies": [
|
||||
"dbus"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "connectivity_plus_platform_interface",
|
||||
"version": "2.0.1",
|
||||
"dependencies": [
|
||||
"flutter",
|
||||
"meta",
|
||||
"plugin_platform_interface"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "args",
|
||||
"version": "2.7.0",
|
||||
"dependencies": []
|
||||
},
|
||||
{
|
||||
"name": "image_picker_platform_interface",
|
||||
"version": "2.11.0",
|
||||
"dependencies": [
|
||||
"cross_file",
|
||||
"flutter",
|
||||
"http",
|
||||
"plugin_platform_interface"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "plugin_platform_interface",
|
||||
"version": "2.1.8",
|
||||
"dependencies": [
|
||||
"meta"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "image_picker_macos",
|
||||
"version": "0.2.1+2",
|
||||
@@ -794,6 +794,14 @@
|
||||
"web"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "url_launcher_platform_interface",
|
||||
"version": "2.3.2",
|
||||
"dependencies": [
|
||||
"flutter",
|
||||
"plugin_platform_interface"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "web",
|
||||
"version": "1.1.1",
|
||||
@@ -809,14 +817,6 @@
|
||||
"web"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "url_launcher_platform_interface",
|
||||
"version": "2.3.2",
|
||||
"dependencies": [
|
||||
"flutter",
|
||||
"plugin_platform_interface"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "path_provider_windows",
|
||||
"version": "2.3.0",
|
||||
@@ -1075,25 +1075,6 @@
|
||||
"version": "1.3.0",
|
||||
"dependencies": []
|
||||
},
|
||||
{
|
||||
"name": "mqtt5_client",
|
||||
"version": "4.13.3",
|
||||
"dependencies": [
|
||||
"characters",
|
||||
"crypto",
|
||||
"event_bus",
|
||||
"meta",
|
||||
"path",
|
||||
"typed_data",
|
||||
"universal_html",
|
||||
"web"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "event_bus",
|
||||
"version": "2.0.1",
|
||||
"dependencies": []
|
||||
},
|
||||
{
|
||||
"name": "shared_preferences",
|
||||
"version": "2.5.3",
|
||||
@@ -1200,6 +1181,25 @@
|
||||
"version": "2.0.0",
|
||||
"dependencies": []
|
||||
},
|
||||
{
|
||||
"name": "mqtt5_client",
|
||||
"version": "4.14.0",
|
||||
"dependencies": [
|
||||
"characters",
|
||||
"crypto",
|
||||
"event_bus",
|
||||
"meta",
|
||||
"path",
|
||||
"typed_data",
|
||||
"universal_html",
|
||||
"web"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "event_bus",
|
||||
"version": "2.0.1",
|
||||
"dependencies": []
|
||||
},
|
||||
{
|
||||
"name": "platform",
|
||||
"version": "3.1.6",
|
||||
@@ -1213,6 +1213,25 @@
|
||||
"path"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "url_launcher_web",
|
||||
"version": "2.4.1",
|
||||
"dependencies": [
|
||||
"flutter",
|
||||
"flutter_web_plugins",
|
||||
"url_launcher_platform_interface",
|
||||
"web"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "file_selector_macos",
|
||||
"version": "0.9.4+3",
|
||||
"dependencies": [
|
||||
"cross_file",
|
||||
"file_selector_platform_interface",
|
||||
"flutter"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "source_helper",
|
||||
"version": "1.3.5",
|
||||
@@ -1247,25 +1266,6 @@
|
||||
"string_scanner"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "url_launcher_web",
|
||||
"version": "2.4.1",
|
||||
"dependencies": [
|
||||
"flutter",
|
||||
"flutter_web_plugins",
|
||||
"url_launcher_platform_interface",
|
||||
"web"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "file_selector_macos",
|
||||
"version": "0.9.4+3",
|
||||
"dependencies": [
|
||||
"cross_file",
|
||||
"file_selector_platform_interface",
|
||||
"flutter"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "logger",
|
||||
"version": "2.6.1",
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -773,6 +773,83 @@ LoggerService.info('Application démarrée');
|
||||
|
||||
Cette architecture garantit un système de logging professionnel, sécurisé et performant, adapté aux besoins de développement tout en protégeant la production. 📝✨
|
||||
|
||||
## 🔐 Gestion des identifiants - Normes NIST SP 800-63B
|
||||
|
||||
### 🎯 Vue d'ensemble
|
||||
|
||||
GEOSECTOR v2.0 implémente les **normes NIST SP 800-63B** pour la gestion des identifiants (usernames et passwords), offrant une sécurité renforcée tout en améliorant l'expérience utilisateur avec des règles plus flexibles et modernes.
|
||||
|
||||
### 📋 Conformité NIST SP 800-63B
|
||||
|
||||
| Exigence NIST | Implémentation | Statut |
|
||||
|---------------|----------------|--------|
|
||||
| **Longueur minimale : 8 caractères** | ✅ MIN = 8 caractères | ✅ CONFORME |
|
||||
| **Longueur maximale : 64 caractères minimum** | ✅ MAX = 64 caractères | ✅ CONFORME |
|
||||
| **Accepter TOUS les caractères ASCII imprimables** | ✅ Aucune restriction sur les caractères | ✅ CONFORME |
|
||||
| **Accepter les espaces** | ✅ Espaces acceptés (début, milieu, fin) | ✅ CONFORME |
|
||||
| **Accepter Unicode (émojis, accents, etc.)** | ✅ Support UTF-8 complet | ✅ CONFORME |
|
||||
| **Vérifier contre les mots de passe compromis** | ✅ API Have I Been Pwned avec k-anonymity | ✅ CONFORME |
|
||||
| **Pas d'obligation de composition** | ✅ Pas d'erreur si manque majuscules/chiffres/spéciaux | ✅ CONFORME |
|
||||
| **Pas de changement périodique forcé** | ✅ Aucune expiration automatique | ✅ CONFORME |
|
||||
| **Permettre les phrases de passe** | ✅ "Mon chat Félix a 3 ans!" accepté | ✅ CONFORME |
|
||||
|
||||
### 🔑 Règles pour les identifiants
|
||||
|
||||
#### **Username (Nom d'utilisateur)**
|
||||
- **Longueur** : 8 à 64 caractères
|
||||
- **Caractères acceptés** : TOUS (lettres, chiffres, espaces, accents, symboles, emojis)
|
||||
- **Exemples valides** :
|
||||
- `jean dupont 75`
|
||||
- `Marie-Claire.2024`
|
||||
- `Pompier Paris 🚒`
|
||||
- `utilisateur@amicale`
|
||||
|
||||
#### **Password (Mot de passe)**
|
||||
- **Longueur** : 8 à 64 caractères
|
||||
- **Aucune règle de composition obligatoire** (plus besoin de majuscules/minuscules/chiffres/spéciaux)
|
||||
- **Phrases de passe recommandées** pour une meilleure mémorisation
|
||||
- **Exemples valides** :
|
||||
- `Mon chat Félix a 3 ans!`
|
||||
- `J'aime les pizzas du vendredi soir`
|
||||
- `Le camion rouge part à 8h30`
|
||||
- `☀️ Soleil brillant sur Paris ☀️`
|
||||
|
||||
### 🎲 Générateurs intelligents
|
||||
|
||||
#### **Générateur de username**
|
||||
Crée des noms d'utilisateur uniques basés sur :
|
||||
- Nom/prénom de la personne
|
||||
- Code postal et ville de l'amicale
|
||||
- Numéro aléatoire pour l'unicité
|
||||
- Peut inclure des espaces et séparateurs (., -, _)
|
||||
|
||||
#### **Générateur de phrases de passe**
|
||||
Génère des phrases de passe mémorables en français :
|
||||
- Phrases naturelles et faciles à retenir
|
||||
- Combinaisons variées (sujets, verbes, compléments)
|
||||
- Ajout optionnel de caractères spéciaux ou emojis
|
||||
- Exemples générés :
|
||||
- `Le chien Max danse dans le jardin!`
|
||||
- `Mon vélo rouge vole 42 fois en été`
|
||||
- `Luna a 7 ans!☀️`
|
||||
|
||||
### ⚠️ Points importants
|
||||
|
||||
1. **Pas de trim()** : Les espaces en début/fin sont préservés et font partie de l'identifiant
|
||||
2. **Pas de vérification password == username** : Sur demande du client, cette règle a été retirée
|
||||
3. **Validation côté API** : L'API vérifie les mots de passe contre la base Have I Been Pwned
|
||||
4. **Rétrocompatibilité** : Les anciens identifiants restent valides
|
||||
|
||||
### 🔄 Impact sur l'expérience utilisateur
|
||||
|
||||
| Aspect | Avant | Après NIST |
|
||||
|--------|-------|------------|
|
||||
| **Complexité** | Règles strictes difficiles à mémoriser | Liberté totale, phrases naturelles |
|
||||
| **Longueur password** | 12-16 caractères obligatoires | 8-64 caractères flexibles |
|
||||
| **Caractères spéciaux** | Obligatoires | Optionnels |
|
||||
| **Mémorisation** | Mots de passe complexes oubliés | Phrases personnelles mémorables |
|
||||
| **Sécurité** | Règles arbitraires | Vérification contre bases de données compromises |
|
||||
|
||||
## 🎯 Gestion des rôles
|
||||
|
||||
### Hiérarchie des permissions
|
||||
|
||||
164
app/claude-code-analyze-flutter.md
Normal file
164
app/claude-code-analyze-flutter.md
Normal file
@@ -0,0 +1,164 @@
|
||||
# 🔧 Claude Code - Analyse et Correction Flutter
|
||||
|
||||
## 📋 Mission
|
||||
|
||||
Tu es un expert Flutter/Dart chargé de nettoyer le code de l'application Geosector. Ta mission est d'analyser tous les fichiers Dart du projet et de corriger TOUTES les erreurs et avertissements détectés par `flutter analyze`.
|
||||
|
||||
## 🎯 Objectifs
|
||||
|
||||
1. **Exécuter l'analyse Flutter** sur l'ensemble du projet
|
||||
2. **Corriger toutes les erreurs** (errors) en priorité
|
||||
3. **Corriger tous les avertissements** (warnings)
|
||||
4. **Corriger les informations** (info) si pertinent
|
||||
5. **Documenter les changements** effectués
|
||||
|
||||
## 📝 Instructions détaillées
|
||||
|
||||
### Étape 1 : Analyse initiale
|
||||
```bash
|
||||
flutter analyze
|
||||
```
|
||||
- Capturer le nombre total d'issues
|
||||
- Identifier les patterns d'erreurs récurrents
|
||||
- Prioriser les corrections (errors → warnings → info)
|
||||
|
||||
### Étape 2 : Corrections par catégorie
|
||||
|
||||
#### 🔴 ERRORS (Priorité maximale)
|
||||
Corriger en priorité toutes les erreurs qui empêchent la compilation :
|
||||
- `undefined_named_parameter`
|
||||
- `undefined_method`
|
||||
- `undefined_getter`
|
||||
- `argument_type_not_assignable`
|
||||
- `return_of_invalid_type`
|
||||
- `creation_with_non_type`
|
||||
|
||||
#### 🟠 WARNINGS (Priorité haute)
|
||||
Corriger les avertissements qui peuvent causer des bugs :
|
||||
- `must_be_immutable`
|
||||
- `unused_element`
|
||||
- `unused_element_parameter`
|
||||
- `unused_local_variable`
|
||||
- `invalid_use_of_protected_member`
|
||||
- `invalid_use_of_visible_for_testing_member`
|
||||
|
||||
#### 🟡 INFO (Priorité moyenne)
|
||||
Corriger les problèmes de qualité de code :
|
||||
- `depend_on_referenced_packages` → Ajouter les dépendances manquantes dans pubspec.yaml
|
||||
- `deprecated_member_use` → Remplacer `withOpacity` par `withValues()`
|
||||
- `use_build_context_synchronously` → Ajouter `if (context.mounted)`
|
||||
- `prefer_const_constructors`
|
||||
- `prefer_const_literals_to_create_immutables`
|
||||
|
||||
### Étape 3 : Patterns de correction spécifiques
|
||||
|
||||
#### Pour `deprecated_member_use` (withOpacity)
|
||||
```dart
|
||||
// ❌ Ancien
|
||||
color: Colors.blue.withOpacity(0.5)
|
||||
|
||||
// ✅ Nouveau
|
||||
color: Colors.blue.withValues(alpha: 127) // 0.5 * 255 = 127
|
||||
```
|
||||
|
||||
#### Pour `use_build_context_synchronously`
|
||||
```dart
|
||||
// ❌ Ancien
|
||||
await someAsyncOperation();
|
||||
Navigator.of(context).pop();
|
||||
|
||||
// ✅ Nouveau
|
||||
await someAsyncOperation();
|
||||
if (context.mounted) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
```
|
||||
|
||||
#### Pour `must_be_immutable` avec HiveObject
|
||||
```dart
|
||||
// Pour les modèles Hive, ajouter une annotation pour ignorer
|
||||
// ignore: must_be_immutable
|
||||
@HiveType(typeId: X)
|
||||
class MyModel extends HiveObject {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Étape 4 : Modules à traiter
|
||||
|
||||
#### 🚫 Module Chat (À ignorer ou supprimer)
|
||||
Le dossier `lib/chat/` contient de nombreuses erreurs car il n'est pas utilisé.
|
||||
**Options** :
|
||||
1. Supprimer complètement le dossier `lib/chat/` si non utilisé
|
||||
2. OU corriger les dépendances manquantes (equatable dans pubspec.yaml)
|
||||
3. OU exclure de l'analyse dans `analysis_options.yaml`
|
||||
|
||||
#### ✅ Modules prioritaires
|
||||
Concentre-toi sur les modules actifs :
|
||||
- `lib/core/` - Services, repositories, models
|
||||
- `lib/presentation/` - UI widgets et pages
|
||||
- `lib/shared/` - Composants partagés
|
||||
|
||||
### Étape 5 : Vérification finale
|
||||
```bash
|
||||
flutter analyze
|
||||
```
|
||||
- Vérifier qu'il n'y a plus d'erreurs
|
||||
- Documenter les warnings restants qui ne peuvent pas être corrigés
|
||||
- Tester que l'application compile et fonctionne
|
||||
|
||||
## 🛠️ Commandes utiles
|
||||
|
||||
```bash
|
||||
# Analyse complète
|
||||
flutter analyze
|
||||
|
||||
# Analyse d'un fichier spécifique
|
||||
flutter analyze lib/presentation/widgets/dashboard_app_bar.dart
|
||||
|
||||
# Format du code
|
||||
flutter format lib/
|
||||
|
||||
# Nettoyer et reconstruire
|
||||
flutter clean && flutter pub get
|
||||
|
||||
# Générer les adapters Hive si nécessaire
|
||||
flutter packages pub run build_runner build --delete-conflicting-outputs
|
||||
```
|
||||
|
||||
## 📊 Rapport attendu
|
||||
|
||||
À la fin, fournir un rapport avec :
|
||||
1. **Nombre d'issues avant** : X errors, Y warnings, Z info
|
||||
2. **Nombre d'issues après** : 0 errors, Y warnings, Z info
|
||||
3. **Liste des fichiers modifiés** avec le type de correction
|
||||
4. **Décisions prises** (ex: suppression du module chat, ajout de dépendances)
|
||||
5. **Problèmes non résolus** et pourquoi
|
||||
|
||||
## ⚠️ Points d'attention
|
||||
|
||||
1. **Ne pas casser le code existant** - Tester après chaque série de corrections
|
||||
2. **Préserver la logique métier** - Ne pas modifier le comportement de l'app
|
||||
3. **Respecter l'architecture** - Maintenir les patterns existants (Repository, Singleton, ValueListenableBuilder)
|
||||
4. **Documenter les suppressions** - Si du code est supprimé, expliquer pourquoi
|
||||
5. **Gérer les dépendances** - Ajouter dans pubspec.yaml si nécessaire
|
||||
|
||||
## 🎯 Résultat attendu
|
||||
|
||||
```bash
|
||||
$ flutter analyze
|
||||
Analyzing app...
|
||||
No issues found!
|
||||
```
|
||||
|
||||
## 📝 Notes spécifiques au projet Geosector
|
||||
|
||||
- **Architecture sans Provider** : Ne pas ajouter Provider
|
||||
- **Hive pour le stockage** : Les warnings `must_be_immutable` sur HiveObject sont normaux
|
||||
- **API First** : Maintenir le pattern de validation API avant sauvegarde locale
|
||||
- **LoggerService** : Utiliser LoggerService au lieu de debugPrint direct
|
||||
- **CurrentUserService/CurrentAmicaleService** : Services singleton à préserver
|
||||
|
||||
---
|
||||
|
||||
**Commence par exécuter `flutter analyze` et montre-moi le résultat pour que nous puissions prioriser les corrections ensemble.**
|
||||
@@ -258,88 +258,7 @@ class _AdminDashboardHomePageState extends State<AdminDashboardHomePage> {
|
||||
|
||||
// Afficher le contenu seulement si les données sont chargées ou en cours de mise à jour
|
||||
if (isDataLoaded || isLoading) ...[
|
||||
// Cartes de synthèse
|
||||
isDesktop
|
||||
? Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: _buildSummaryCard(
|
||||
context,
|
||||
'Passages totaux',
|
||||
totalPassages.toString(),
|
||||
Icons.map_outlined,
|
||||
AppTheme.primaryColor,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: AppTheme.spacingM),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: _buildSummaryCard(
|
||||
context,
|
||||
'Montant collecté',
|
||||
'${totalAmounts.toStringAsFixed(2)} €',
|
||||
Icons.euro_outlined,
|
||||
AppTheme.buttonSuccessColor,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: AppTheme.spacingM),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: SectorDistributionCard(
|
||||
key: ValueKey('sector_distribution_${isFirstLoad ? 'initial' : 'refreshed'}_$isLoading'),
|
||||
height: 200,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
children: [
|
||||
_buildSummaryCard(
|
||||
context,
|
||||
'Passages totaux',
|
||||
totalPassages.toString(),
|
||||
Icons.map_outlined,
|
||||
AppTheme.primaryColor,
|
||||
),
|
||||
const SizedBox(height: AppTheme.spacingM),
|
||||
_buildSummaryCard(
|
||||
context,
|
||||
'Montant collecté',
|
||||
'${totalAmounts.toStringAsFixed(2)} €',
|
||||
Icons.euro_outlined,
|
||||
AppTheme.buttonSuccessColor,
|
||||
),
|
||||
const SizedBox(height: AppTheme.spacingM),
|
||||
SectorDistributionCard(
|
||||
key: ValueKey('sector_distribution_${isFirstLoad ? 'initial' : 'refreshed'}_$isLoading'),
|
||||
height: 200,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(height: AppTheme.spacingL),
|
||||
|
||||
// Graphique d'activité
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(AppTheme.borderRadiusMedium),
|
||||
boxShadow: AppTheme.cardShadow,
|
||||
),
|
||||
child: ActivityChart(
|
||||
key: ValueKey('activity_chart_${isFirstLoad ? 'initial' : 'refreshed'}_$isLoading'),
|
||||
height: 350,
|
||||
showAllPassages: true, // Tous les passages, pas seulement ceux de l'utilisateur courant
|
||||
title: 'Passages réalisés par jour (15 derniers jours)',
|
||||
daysToShow: 15,
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: AppTheme.spacingL),
|
||||
|
||||
// Graphiques de répartition
|
||||
// LIGNE 1 : Graphiques de répartition (type de passage et mode de paiement)
|
||||
isDesktop
|
||||
? Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -363,6 +282,33 @@ class _AdminDashboardHomePageState extends State<AdminDashboardHomePage> {
|
||||
|
||||
const SizedBox(height: AppTheme.spacingL),
|
||||
|
||||
// LIGNE 2 : Carte de répartition par secteur (pleine largeur)
|
||||
SectorDistributionCard(
|
||||
key: ValueKey('sector_distribution_${isFirstLoad ? 'initial' : 'refreshed'}_$isLoading'),
|
||||
title: 'Répartition sur les 31 secteurs',
|
||||
height: 500, // Hauteur maximale pour afficher tous les secteurs
|
||||
),
|
||||
|
||||
const SizedBox(height: AppTheme.spacingL),
|
||||
|
||||
// LIGNE 3 : Graphique d'activité
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(AppTheme.borderRadiusMedium),
|
||||
boxShadow: AppTheme.cardShadow,
|
||||
),
|
||||
child: ActivityChart(
|
||||
key: ValueKey('activity_chart_${isFirstLoad ? 'initial' : 'refreshed'}_$isLoading'),
|
||||
height: 350,
|
||||
showAllPassages: true, // Tous les passages, pas seulement ceux de l'utilisateur courant
|
||||
title: 'Passages réalisés par jour (15 derniers jours)',
|
||||
daysToShow: 15,
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: AppTheme.spacingL),
|
||||
|
||||
// Actions rapides - uniquement visible sur le web
|
||||
if (kIsWeb) ...[
|
||||
Container(
|
||||
@@ -415,61 +361,6 @@ class _AdminDashboardHomePageState extends State<AdminDashboardHomePage> {
|
||||
]);
|
||||
}
|
||||
|
||||
Widget _buildSummaryCard(
|
||||
BuildContext context,
|
||||
String label,
|
||||
String value,
|
||||
IconData icon,
|
||||
Color color,
|
||||
) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(AppTheme.spacingM),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(AppTheme.borderRadiusMedium),
|
||||
boxShadow: AppTheme.cardShadow,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
decoration: BoxDecoration(
|
||||
color: color.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(AppTheme.borderRadiusSmall),
|
||||
),
|
||||
child: Icon(
|
||||
icon,
|
||||
color: color,
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: AppTheme.spacingM),
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppTheme.spacingM),
|
||||
Text(
|
||||
value,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 24,
|
||||
color: color,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Construit la carte de répartition par type de passage avec liste
|
||||
Widget _buildPassageTypeCard(BuildContext context) {
|
||||
return PassageSummaryCard(
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:geosector_app/app.dart'; // Pour accéder aux instances globales
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
import 'package:geosector_app/presentation/widgets/dashboard_layout.dart';
|
||||
import 'package:geosector_app/core/constants/app_keys.dart';
|
||||
@@ -51,6 +52,9 @@ class _AdminDashboardPageState extends State<AdminDashboardPage> with WidgetsBin
|
||||
|
||||
// Référence à la boîte Hive pour les paramètres
|
||||
late Box _settingsBox;
|
||||
|
||||
// Listener pour les changements de paramètres
|
||||
late ValueListenable<Box<dynamic>> _settingsListenable;
|
||||
|
||||
// Liste des éléments de navigation de base (toujours visibles)
|
||||
final List<_NavigationItem> _baseNavigationItems = [
|
||||
@@ -226,7 +230,11 @@ class _AdminDashboardPageState extends State<AdminDashboardPage> with WidgetsBin
|
||||
// Les pages seront construites dynamiquement dans build()
|
||||
|
||||
// Initialiser et charger les paramètres
|
||||
_initSettings();
|
||||
_initSettings().then((_) {
|
||||
// Écouter les changements de la boîte de paramètres après l'initialisation
|
||||
_settingsListenable = _settingsBox.listenable(keys: ['adminSelectedPageIndex']);
|
||||
_settingsListenable.addListener(_onSettingsChanged);
|
||||
});
|
||||
|
||||
// Vérifier si des données sont en cours de chargement
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
@@ -241,6 +249,7 @@ class _AdminDashboardPageState extends State<AdminDashboardPage> with WidgetsBin
|
||||
void dispose() {
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
userRepository.removeListener(_handleUserRepositoryChanges);
|
||||
_settingsListenable.removeListener(_onSettingsChanged);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -248,6 +257,16 @@ class _AdminDashboardPageState extends State<AdminDashboardPage> with WidgetsBin
|
||||
void _handleUserRepositoryChanges() {
|
||||
_checkLoadingState();
|
||||
}
|
||||
|
||||
// Méthode pour gérer les changements de paramètres
|
||||
void _onSettingsChanged() {
|
||||
final newIndex = _settingsBox.get('adminSelectedPageIndex');
|
||||
if (newIndex != null && newIndex is int && newIndex != _selectedIndex) {
|
||||
setState(() {
|
||||
_selectedIndex = newIndex;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Méthode pour vérifier l'état de chargement (barre de progression désactivée)
|
||||
void _checkLoadingState() {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:geosector_app/app.dart'; // Pour accéder aux instances globales
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:geosector_app/core/constants/app_keys.dart';
|
||||
import 'package:geosector_app/core/data/models/passage_model.dart';
|
||||
import 'package:geosector_app/core/data/models/sector_model.dart';
|
||||
@@ -84,6 +85,8 @@ class _AdminHistoryPageState extends State<AdminHistoryPage> {
|
||||
super.initState();
|
||||
// Initialiser les filtres
|
||||
_initializeFilters();
|
||||
// Charger les filtres présélectionnés depuis Hive si disponibles
|
||||
_loadPreselectedFilters();
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -172,6 +175,40 @@ class _AdminHistoryPageState extends State<AdminHistoryPage> {
|
||||
selectedDateRange = null;
|
||||
}
|
||||
|
||||
// Charger les filtres présélectionnés depuis Hive
|
||||
void _loadPreselectedFilters() {
|
||||
try {
|
||||
// Utiliser Hive directement sans async
|
||||
if (Hive.isBoxOpen(AppKeys.settingsBoxName)) {
|
||||
final settingsBox = Hive.box(AppKeys.settingsBoxName);
|
||||
|
||||
// Charger le secteur présélectionné
|
||||
final int? preselectedSectorId = settingsBox.get('history_selectedSectorId');
|
||||
final String? preselectedSectorName = settingsBox.get('history_selectedSectorName');
|
||||
final int? preselectedTypeId = settingsBox.get('history_selectedTypeId');
|
||||
|
||||
if (preselectedSectorId != null && preselectedSectorName != null) {
|
||||
selectedSectorId = preselectedSectorId;
|
||||
selectedSector = preselectedSectorName;
|
||||
|
||||
debugPrint('Secteur présélectionné: $preselectedSectorName (ID: $preselectedSectorId)');
|
||||
}
|
||||
|
||||
if (preselectedTypeId != null) {
|
||||
selectedType = preselectedTypeId.toString();
|
||||
debugPrint('Type de passage présélectionné: $preselectedTypeId');
|
||||
}
|
||||
|
||||
// Nettoyer les valeurs après utilisation pour ne pas les réutiliser la prochaine fois
|
||||
settingsBox.delete('history_selectedSectorId');
|
||||
settingsBox.delete('history_selectedSectorName');
|
||||
settingsBox.delete('history_selectedTypeId');
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors du chargement des filtres présélectionnés: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_searchController.dispose();
|
||||
|
||||
@@ -85,6 +85,9 @@ class _AdminMapPageState extends State<AdminMapPage> {
|
||||
|
||||
// Référence à la boîte Hive pour les paramètres
|
||||
late Box _settingsBox;
|
||||
|
||||
// Listener pour les changements de paramètres
|
||||
late ValueListenable<Box<dynamic>> _settingsListenable;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -92,6 +95,11 @@ class _AdminMapPageState extends State<AdminMapPage> {
|
||||
_initSettings().then((_) {
|
||||
_loadSectors();
|
||||
_loadPassages();
|
||||
|
||||
// Écouter les changements du secteur sélectionné
|
||||
_settingsListenable = _settingsBox.listenable(keys: ['admin_selectedSectorId']);
|
||||
_settingsListenable.addListener(_onSectorSelectionChanged);
|
||||
|
||||
// Centrer la carte une seule fois après le chargement initial
|
||||
Future.delayed(const Duration(milliseconds: 100), () {
|
||||
if (_selectedSectorId != null && _sectors.any((s) => s['id'] == _selectedSectorId)) {
|
||||
@@ -128,7 +136,34 @@ class _AdminMapPageState extends State<AdminMapPage> {
|
||||
_currentZoom = savedZoom;
|
||||
}
|
||||
}
|
||||
|
||||
// Méthode pour gérer les changements de sélection de secteur
|
||||
void _onSectorSelectionChanged() {
|
||||
final newSectorId = _settingsBox.get('admin_selectedSectorId');
|
||||
if (newSectorId != null && newSectorId != _selectedSectorId) {
|
||||
setState(() {
|
||||
_selectedSectorId = newSectorId;
|
||||
});
|
||||
|
||||
// Recharger les passages pour le nouveau secteur
|
||||
_loadPassages();
|
||||
|
||||
// Attendre que le build soit fait puis centrer sur le secteur
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (_sectors.any((s) => s['id'] == _selectedSectorId)) {
|
||||
_centerMapOnSpecificSector(_selectedSectorId!);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_settingsListenable.removeListener(_onSectorSelectionChanged);
|
||||
_mapController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
// Sauvegarder les paramètres utilisateur
|
||||
void _saveSettings() {
|
||||
// Sauvegarder le secteur sélectionné
|
||||
|
||||
@@ -436,7 +436,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||
final success =
|
||||
await userRepository.loginWithSpinner(
|
||||
context,
|
||||
_usernameController.text.trim(),
|
||||
_usernameController.text, // NIST: ne pas faire de trim
|
||||
_passwordController.text,
|
||||
type: _loginType,
|
||||
);
|
||||
@@ -580,7 +580,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||
final success = await userRepository
|
||||
.loginWithSpinner(
|
||||
context,
|
||||
_usernameController.text.trim(),
|
||||
_usernameController.text, // NIST: ne pas faire de trim
|
||||
_passwordController.text,
|
||||
type: _loginType,
|
||||
);
|
||||
@@ -648,28 +648,64 @@ class _LoginPageState extends State<LoginPage> {
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Inscription administrateur uniquement
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
'Pas encore de compte ?',
|
||||
style: theme.textTheme.bodyMedium,
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
context.go('/register');
|
||||
},
|
||||
child: const Text(
|
||||
'Inscription Administrateur',
|
||||
style: TextStyle(
|
||||
color: Colors.blue,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
// Inscription administrateur uniquement en mode admin
|
||||
if (_loginType == 'admin') ...[
|
||||
// Détecter si on est sur mobile
|
||||
LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
final isMobile = constraints.maxWidth < 400;
|
||||
|
||||
if (isMobile) {
|
||||
// Sur mobile : afficher sur deux lignes
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
'Pas encore de compte ?',
|
||||
style: theme.textTheme.bodyMedium,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
context.go('/register');
|
||||
},
|
||||
child: const Text(
|
||||
'Inscription Administrateur',
|
||||
style: TextStyle(
|
||||
color: Colors.blue,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
// Sur desktop : afficher sur une ligne
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
'Pas encore de compte ?',
|
||||
style: theme.textTheme.bodyMedium,
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
context.go('/register');
|
||||
},
|
||||
child: const Text(
|
||||
'Inscription Administrateur',
|
||||
style: TextStyle(
|
||||
color: Colors.blue,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
|
||||
// Lien vers la page d'accueil
|
||||
TextButton(
|
||||
@@ -683,6 +719,35 @@ class _LoginPageState extends State<LoginPage> {
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// Badge de version dans la card
|
||||
if (_appVersion.isNotEmpty) ...[
|
||||
const SizedBox(height: 16),
|
||||
Center(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
vertical: 6,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.primary.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: theme.colorScheme.primary.withOpacity(0.3),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
'v$_appVersion',
|
||||
style: theme.textTheme.bodySmall?.copyWith(
|
||||
color: theme.colorScheme.primary.withOpacity(0.8),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -694,34 +759,6 @@ class _LoginPageState extends State<LoginPage> {
|
||||
),
|
||||
),
|
||||
),
|
||||
// Badge de version en bas à droite
|
||||
if (_appVersion.isNotEmpty)
|
||||
Positioned(
|
||||
bottom: 16,
|
||||
right: 16,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
vertical: 4,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.primary.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: theme.colorScheme.primary.withOpacity(0.3),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
'v$_appVersion',
|
||||
style: theme.textTheme.bodySmall?.copyWith(
|
||||
color: theme.colorScheme.primary.withOpacity(0.8),
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -6,6 +6,7 @@ class CustomTextField extends StatelessWidget {
|
||||
final String label;
|
||||
final String? hintText;
|
||||
final String? helperText;
|
||||
final int? helperMaxLines;
|
||||
final IconData? prefixIcon;
|
||||
final Widget? suffixIcon;
|
||||
final bool readOnly;
|
||||
@@ -33,6 +34,7 @@ class CustomTextField extends StatelessWidget {
|
||||
required this.label,
|
||||
this.hintText,
|
||||
this.helperText,
|
||||
this.helperMaxLines,
|
||||
this.prefixIcon,
|
||||
this.suffixIcon,
|
||||
this.readOnly = false,
|
||||
@@ -79,6 +81,7 @@ class CustomTextField extends StatelessWidget {
|
||||
labelText: isRequired ? "$label *" : label,
|
||||
hintText: hintText,
|
||||
helperText: helperText,
|
||||
helperMaxLines: helperMaxLines,
|
||||
prefixIcon: prefixIcon != null ? Icon(prefixIcon) : null,
|
||||
suffixIcon: suffixIcon,
|
||||
border: const OutlineInputBorder(),
|
||||
@@ -150,6 +153,7 @@ class CustomTextField extends StatelessWidget {
|
||||
decoration: InputDecoration(
|
||||
hintText: hintText,
|
||||
helperText: helperText,
|
||||
helperMaxLines: helperMaxLines,
|
||||
prefixIcon: prefixIcon != null ? Icon(prefixIcon) : null,
|
||||
suffixIcon: suffixIcon,
|
||||
border: OutlineInputBorder(
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:geosector_app/app.dart';
|
||||
import 'package:geosector_app/core/services/app_info_service.dart';
|
||||
import 'package:geosector_app/core/services/current_amicale_service.dart';
|
||||
import 'package:geosector_app/presentation/widgets/connectivity_indicator.dart';
|
||||
import 'package:geosector_app/presentation/widgets/user_form_dialog.dart';
|
||||
import 'package:geosector_app/presentation/widgets/passage_form_dialog.dart';
|
||||
@@ -42,7 +44,10 @@ class DashboardAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
|
||||
// Vérifier si le logo de l'amicale est présent pour ajuster la largeur du leading
|
||||
final amicale = CurrentAmicaleService.instance.currentAmicale;
|
||||
final hasAmicaleLogo = amicale?.logoBase64 != null && amicale!.logoBase64!.isNotEmpty;
|
||||
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
@@ -52,6 +57,8 @@ class DashboardAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
foregroundColor: theme.colorScheme.onPrimary,
|
||||
elevation: 4,
|
||||
leading: _buildLogo(),
|
||||
// Ajuster la largeur du leading si le logo de l'amicale est présent
|
||||
leadingWidth: hasAmicaleLogo ? 110 : 56, // 56 par défaut, 110 pour 2 logos + espacement
|
||||
actions: _buildActions(context),
|
||||
),
|
||||
// Bordure colorée selon le rôle
|
||||
@@ -65,6 +72,9 @@ class DashboardAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
|
||||
/// Construction du logo dans l'AppBar
|
||||
Widget _buildLogo() {
|
||||
final amicale = CurrentAmicaleService.instance.currentAmicale;
|
||||
final logoBase64 = amicale?.logoBase64;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
@@ -75,11 +85,56 @@ class DashboardAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
width: 40,
|
||||
height: 40,
|
||||
),
|
||||
// Afficher le logo de l'amicale s'il est disponible
|
||||
if (logoBase64 != null && logoBase64.isNotEmpty) ...[
|
||||
const SizedBox(width: 8),
|
||||
_buildAmicaleLogo(logoBase64),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Construction du logo de l'amicale à partir du Base64
|
||||
Widget _buildAmicaleLogo(String logoBase64) {
|
||||
try {
|
||||
// Le logoBase64 peut être au format "data:image/png;base64,..." ou juste la chaîne base64
|
||||
String base64String = logoBase64;
|
||||
if (logoBase64.contains('base64,')) {
|
||||
base64String = logoBase64.split('base64,').last;
|
||||
}
|
||||
|
||||
final decodedBytes = base64Decode(base64String);
|
||||
|
||||
return Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
color: Colors.white,
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
child: Image.memory(
|
||||
decodedBytes,
|
||||
width: 40,
|
||||
height: 40,
|
||||
fit: BoxFit.contain,
|
||||
errorBuilder: (context, error, stackTrace) {
|
||||
// En cas d'erreur de décodage, ne rien afficher
|
||||
debugPrint('Erreur lors du chargement du logo amicale: $error');
|
||||
return const SizedBox.shrink();
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
// En cas d'erreur, ne rien afficher
|
||||
debugPrint('Erreur lors du décodage du logo amicale: $e');
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}
|
||||
|
||||
/// Construction des actions de l'AppBar
|
||||
List<Widget> _buildActions(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
@@ -263,9 +318,6 @@ class DashboardAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
return Text(title);
|
||||
}
|
||||
|
||||
// Construire un titre composé en fonction du rôle de l'utilisateur
|
||||
final String prefix = isAdmin ? 'Administration' : title;
|
||||
|
||||
// Utiliser LayoutBuilder pour détecter la largeur disponible
|
||||
return LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
@@ -274,20 +326,14 @@ class DashboardAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
final isMobilePlatform = Theme.of(context).platform == TargetPlatform.android ||
|
||||
Theme.of(context).platform == TargetPlatform.iOS;
|
||||
|
||||
// Cacher le titre de page sur mobile ou écrans étroits
|
||||
// Sur mobile ou écrans étroits, afficher seulement le titre principal
|
||||
if (isNarrowScreen || isMobilePlatform) {
|
||||
return Text(prefix);
|
||||
return Text(title);
|
||||
}
|
||||
|
||||
// Afficher le titre complet sur écrans larges (web desktop)
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(prefix),
|
||||
const Text(' - '),
|
||||
Text(pageTitle!),
|
||||
],
|
||||
);
|
||||
// Sur écrans larges (web desktop), afficher le titre de la page ou le titre principal
|
||||
// Pour les admins, on affiche directement le titre de la page sans préfixe
|
||||
return Text(pageTitle!);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -155,14 +155,25 @@ class _ResponsiveNavigationState extends State<ResponsiveNavigation> {
|
||||
/// Construction de la barre de navigation inférieure pour mobile
|
||||
Widget _buildBottomNavigationBar() {
|
||||
final theme = Theme.of(context);
|
||||
|
||||
// Définir les couleurs selon le rôle (admin = rouge, user = vert)
|
||||
final Color selectedColor = widget.isAdmin ? Colors.red : Colors.green;
|
||||
|
||||
return NavigationBar(
|
||||
selectedIndex: widget.selectedIndex,
|
||||
onDestinationSelected: widget.onDestinationSelected,
|
||||
backgroundColor: theme.colorScheme.surface,
|
||||
elevation: 8,
|
||||
labelBehavior: NavigationDestinationLabelBehavior.alwaysHide,
|
||||
destinations: widget.destinations,
|
||||
return Theme(
|
||||
data: theme.copyWith(
|
||||
colorScheme: theme.colorScheme.copyWith(
|
||||
onSecondaryContainer: selectedColor, // Couleur de l'icône sélectionnée
|
||||
secondaryContainer: selectedColor.withOpacity(0.15), // Couleur de fond de l'indicateur
|
||||
),
|
||||
),
|
||||
child: NavigationBar(
|
||||
selectedIndex: widget.selectedIndex,
|
||||
onDestinationSelected: widget.onDestinationSelected,
|
||||
backgroundColor: theme.colorScheme.surface,
|
||||
elevation: 8,
|
||||
labelBehavior: NavigationDestinationLabelBehavior.alwaysHide,
|
||||
destinations: widget.destinations,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -345,6 +356,10 @@ class _ResponsiveNavigationState extends State<ResponsiveNavigation> {
|
||||
final theme = Theme.of(context);
|
||||
final isSelected = widget.selectedIndex == index;
|
||||
final IconData? iconData = (icon is Icon) ? (icon).icon : null;
|
||||
|
||||
// Définir les couleurs selon le rôle (admin = rouge, user = vert)
|
||||
final Color selectedColor = widget.isAdmin ? Colors.red : Colors.green;
|
||||
final Color unselectedColor = theme.colorScheme.onSurface.withOpacity(0.6);
|
||||
|
||||
// Remplacer certains titres si l'interface est de type "user"
|
||||
String displayTitle = title;
|
||||
@@ -371,16 +386,14 @@ class _ResponsiveNavigationState extends State<ResponsiveNavigation> {
|
||||
height: 50,
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected
|
||||
? theme.colorScheme.primary.withOpacity(0.1)
|
||||
? selectedColor.withOpacity(0.1)
|
||||
: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: iconData != null
|
||||
? Icon(
|
||||
iconData,
|
||||
color: isSelected
|
||||
? theme.colorScheme.primary
|
||||
: theme.colorScheme.onSurface.withOpacity(0.6),
|
||||
color: isSelected ? selectedColor : unselectedColor,
|
||||
size: 24,
|
||||
)
|
||||
: icon,
|
||||
@@ -394,22 +407,18 @@ class _ResponsiveNavigationState extends State<ResponsiveNavigation> {
|
||||
leading: iconData != null
|
||||
? Icon(
|
||||
iconData,
|
||||
color: isSelected
|
||||
? theme.colorScheme.primary
|
||||
: theme.colorScheme.onSurface.withOpacity(0.6),
|
||||
color: isSelected ? selectedColor : unselectedColor,
|
||||
)
|
||||
: icon,
|
||||
title: Text(
|
||||
displayTitle,
|
||||
style: TextStyle(
|
||||
color: isSelected
|
||||
? theme.colorScheme.primary
|
||||
: theme.colorScheme.onSurface,
|
||||
color: isSelected ? selectedColor : theme.colorScheme.onSurface,
|
||||
fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
|
||||
),
|
||||
),
|
||||
tileColor:
|
||||
isSelected ? theme.colorScheme.primary.withOpacity(0.1) : null,
|
||||
isSelected ? selectedColor.withOpacity(0.1) : null,
|
||||
onTap: () {
|
||||
widget.onDestinationSelected(index);
|
||||
},
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:geosector_app/core/data/models/passage_model.dart';
|
||||
import 'package:geosector_app/core/data/models/sector_model.dart';
|
||||
import 'package:geosector_app/core/constants/app_keys.dart';
|
||||
import 'package:geosector_app/core/theme/app_theme.dart';
|
||||
import 'package:geosector_app/core/services/current_user_service.dart';
|
||||
|
||||
class SectorDistributionCard extends StatelessWidget {
|
||||
// Enum pour les types de tri
|
||||
enum SortType { name, count, progress }
|
||||
enum SortOrder { none, asc, desc }
|
||||
|
||||
class SectorDistributionCard extends StatefulWidget {
|
||||
final String title;
|
||||
final double? height;
|
||||
final EdgeInsetsGeometry? padding;
|
||||
@@ -17,11 +23,81 @@ class SectorDistributionCard extends StatelessWidget {
|
||||
this.padding,
|
||||
});
|
||||
|
||||
@override
|
||||
State<SectorDistributionCard> createState() => _SectorDistributionCardState();
|
||||
}
|
||||
|
||||
class _SectorDistributionCardState extends State<SectorDistributionCard> {
|
||||
SortType? _currentSortType;
|
||||
SortOrder _currentSortOrder = SortOrder.none;
|
||||
|
||||
void _onSortPressed(SortType sortType) {
|
||||
setState(() {
|
||||
if (_currentSortType == sortType) {
|
||||
// Cycle through: none -> asc -> desc -> none
|
||||
if (_currentSortOrder == SortOrder.none) {
|
||||
_currentSortOrder = SortOrder.asc;
|
||||
} else if (_currentSortOrder == SortOrder.asc) {
|
||||
_currentSortOrder = SortOrder.desc;
|
||||
} else {
|
||||
_currentSortOrder = SortOrder.none;
|
||||
_currentSortType = null;
|
||||
}
|
||||
} else {
|
||||
_currentSortType = sortType;
|
||||
_currentSortOrder = SortOrder.asc;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Widget _buildSortButton(String label, SortType sortType) {
|
||||
final isActive = _currentSortType == sortType && _currentSortOrder != SortOrder.none;
|
||||
final isAsc = _currentSortType == sortType && _currentSortOrder == SortOrder.asc;
|
||||
final isDesc = _currentSortType == sortType && _currentSortOrder == SortOrder.desc;
|
||||
|
||||
return InkWell(
|
||||
onTap: () => _onSortPressed(sortType),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: isActive ? Colors.blue.withOpacity(0.1) : Colors.grey.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
border: Border.all(
|
||||
color: isActive ? Colors.blue : Colors.grey[400]!,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: isActive ? FontWeight.bold : FontWeight.normal,
|
||||
color: isActive ? Colors.blue : Colors.grey[700],
|
||||
),
|
||||
),
|
||||
if (isActive) ...[
|
||||
const SizedBox(width: 2),
|
||||
Icon(
|
||||
isAsc ? Icons.arrow_upward : Icons.arrow_downward,
|
||||
size: 12,
|
||||
color: Colors.blue,
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: height,
|
||||
padding: padding ?? const EdgeInsets.all(AppTheme.spacingM),
|
||||
height: widget.height,
|
||||
padding: widget.padding ?? const EdgeInsets.all(AppTheme.spacingM),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(AppTheme.borderRadiusMedium),
|
||||
@@ -30,12 +106,29 @@ class SectorDistributionCard extends StatelessWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16,
|
||||
),
|
||||
// Ligne du titre avec boutons de tri
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
widget.title,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
// Boutons de tri groupés
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
_buildSortButton('Nom', SortType.name),
|
||||
const SizedBox(width: 4),
|
||||
_buildSortButton('Nb', SortType.count),
|
||||
const SizedBox(width: 4),
|
||||
_buildSortButton('%', SortType.progress),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppTheme.spacingM),
|
||||
Expanded(
|
||||
@@ -75,6 +168,16 @@ class SectorDistributionCard extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
// Appliquer le tri
|
||||
_applySorting(sectorStats);
|
||||
|
||||
// Trouver le maximum de passages pour un secteur
|
||||
final maxCount = sectorStats.fold<int>(
|
||||
0,
|
||||
(max, sector) => sector['count'] > max ? sector['count'] : max,
|
||||
);
|
||||
|
||||
// Liste des secteurs directement sans sous-titre
|
||||
return ListView.builder(
|
||||
itemCount: sectorStats.length,
|
||||
itemBuilder: (context, index) {
|
||||
@@ -84,6 +187,7 @@ class SectorDistributionCard extends StatelessWidget {
|
||||
sector['count'],
|
||||
Color(sector['color']),
|
||||
sectorStats,
|
||||
maxCount, // Passer le max pour calculer les proportions
|
||||
);
|
||||
},
|
||||
);
|
||||
@@ -103,83 +207,281 @@ class SectorDistributionCard extends StatelessWidget {
|
||||
final List<SectorModel> sectors = sectorsBox.values.toList();
|
||||
final List<PassageModel> passages = passagesBox.values.toList();
|
||||
|
||||
// Compter les passages par secteur (en excluant ceux où fkType==2)
|
||||
final Map<int, int> sectorCounts = {};
|
||||
|
||||
for (final passage in passages) {
|
||||
// Exclure les passages où fkType==2 et ceux sans secteur
|
||||
if (passage.fkType != 2 && passage.fkSector != null) {
|
||||
sectorCounts[passage.fkSector!] =
|
||||
(sectorCounts[passage.fkSector!] ?? 0) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Préparer les données pour l'affichage
|
||||
// Préparer les données pour l'affichage - AFFICHER TOUS LES SECTEURS
|
||||
List<Map<String, dynamic>> stats = [];
|
||||
|
||||
for (final sector in sectors) {
|
||||
final count = sectorCounts[sector.id] ?? 0;
|
||||
if (count > 0) {
|
||||
stats.add({
|
||||
'name': sector.libelle,
|
||||
'count': count,
|
||||
'color': sector.color.isEmpty
|
||||
? 0xFF4B77BE
|
||||
: int.tryParse(sector.color.replaceAll('#', '0xFF')) ??
|
||||
0xFF4B77BE,
|
||||
});
|
||||
// Compter les passages par type pour ce secteur
|
||||
Map<int, int> passagesByType = {};
|
||||
int totalCount = 0;
|
||||
int passagesNotType2 = 0;
|
||||
|
||||
// Compter tous les passages pour ce secteur
|
||||
for (final passage in passages) {
|
||||
if (passage.fkSector == sector.id) {
|
||||
final type = passage.fkType;
|
||||
passagesByType[type] = (passagesByType[type] ?? 0) + 1;
|
||||
totalCount++;
|
||||
if (type != 2) {
|
||||
passagesNotType2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculer le pourcentage d'avancement
|
||||
final int progressPercentage = totalCount > 0
|
||||
? ((passagesNotType2 / totalCount) * 100).round()
|
||||
: 0;
|
||||
|
||||
stats.add({
|
||||
'id': sector.id,
|
||||
'name': sector.libelle,
|
||||
'count': totalCount,
|
||||
'passagesByType': passagesByType,
|
||||
'progressPercentage': progressPercentage,
|
||||
'color': sector.color.isEmpty
|
||||
? 0xFF4B77BE
|
||||
: int.tryParse(sector.color.replaceAll('#', '0xFF')) ??
|
||||
0xFF4B77BE,
|
||||
});
|
||||
}
|
||||
|
||||
// Trier par nombre de passages (décroissant)
|
||||
stats.sort((a, b) => (b['count'] as int).compareTo(a['count'] as int));
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
void _applySorting(List<Map<String, dynamic>> stats) {
|
||||
if (_currentSortType == null || _currentSortOrder == SortOrder.none) {
|
||||
// Tri par défaut : par nombre de passages décroissant, puis par nom
|
||||
stats.sort((a, b) {
|
||||
int countCompare = (b['count'] as int).compareTo(a['count'] as int);
|
||||
if (countCompare != 0) return countCompare;
|
||||
return (a['name'] as String).compareTo(b['name'] as String);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
switch (_currentSortType!) {
|
||||
case SortType.name:
|
||||
stats.sort((a, b) {
|
||||
final result = (a['name'] as String).compareTo(b['name'] as String);
|
||||
return _currentSortOrder == SortOrder.asc ? result : -result;
|
||||
});
|
||||
break;
|
||||
case SortType.count:
|
||||
stats.sort((a, b) {
|
||||
final result = (a['count'] as int).compareTo(b['count'] as int);
|
||||
return _currentSortOrder == SortOrder.asc ? result : -result;
|
||||
});
|
||||
break;
|
||||
case SortType.progress:
|
||||
stats.sort((a, b) {
|
||||
final result = (a['progressPercentage'] as int).compareTo(b['progressPercentage'] as int);
|
||||
return _currentSortOrder == SortOrder.asc ? result : -result;
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildSectorItem(
|
||||
String name,
|
||||
int count,
|
||||
Color color,
|
||||
List<Map<String, dynamic>> allStats,
|
||||
int maxCount,
|
||||
) {
|
||||
final totalCount =
|
||||
allStats.fold(0, (sum, item) => sum + (item['count'] as int));
|
||||
final percentage = totalCount > 0 ? (count / totalCount) * 100 : 0;
|
||||
// Récupérer les données du secteur actuel
|
||||
final sectorData = allStats.firstWhere((s) => s['name'] == name);
|
||||
final Map<int, int> passagesByType = sectorData['passagesByType'] ?? {};
|
||||
final int progressPercentage = sectorData['progressPercentage'] ?? 0;
|
||||
final int sectorId = sectorData['id'] ?? 0;
|
||||
|
||||
// Calculer le ratio par rapport au maximum (éviter division par zéro)
|
||||
final double widthRatio = maxCount > 0 ? count / maxCount : 0;
|
||||
|
||||
// Style différent pour les secteurs sans passages
|
||||
final bool hasPassages = count > 0;
|
||||
final textColor = hasPassages ? Colors.black87 : Colors.grey;
|
||||
|
||||
// Vérifier si l'utilisateur est admin
|
||||
final bool isAdmin = CurrentUserService.instance.canAccessAdmin;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: AppTheme.spacingS),
|
||||
padding: const EdgeInsets.only(bottom: AppTheme.spacingM),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Nom du secteur et total
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
name,
|
||||
style: const TextStyle(fontSize: 14),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
child: isAdmin
|
||||
? InkWell(
|
||||
onTap: () {
|
||||
// Sauvegarder le secteur sélectionné et l'index de la page carte dans Hive
|
||||
final settingsBox = Hive.box(AppKeys.settingsBoxName);
|
||||
settingsBox.put('admin_selectedSectorId', sectorId);
|
||||
settingsBox.put('adminSelectedPageIndex', 4); // Index de la page carte
|
||||
|
||||
// Naviguer vers le dashboard admin qui chargera la page carte
|
||||
context.go('/admin');
|
||||
},
|
||||
child: Text(
|
||||
name,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: textColor,
|
||||
fontWeight: hasPassages ? FontWeight.w600 : FontWeight.w300,
|
||||
decoration: TextDecoration.underline,
|
||||
decorationColor: textColor.withOpacity(0.5),
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
name,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: textColor,
|
||||
fontWeight: hasPassages ? FontWeight.w600 : FontWeight.w300,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'$count (${percentage.toInt()}%)',
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14,
|
||||
hasPassages
|
||||
? '$count passages ($progressPercentage% d\'avancement)'
|
||||
: '0 passage',
|
||||
style: TextStyle(
|
||||
fontWeight: hasPassages ? FontWeight.bold : FontWeight.normal,
|
||||
fontSize: 13,
|
||||
color: textColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
LinearProgressIndicator(
|
||||
value: percentage / 100,
|
||||
backgroundColor: Colors.grey[200],
|
||||
valueColor: AlwaysStoppedAnimation<Color>(color),
|
||||
minHeight: 8,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
const SizedBox(height: 6),
|
||||
// Barre horizontale cumulée avec largeur proportionnelle
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: FractionallySizedBox(
|
||||
widthFactor: widthRatio,
|
||||
child: _buildStackedBar(passagesByType, count, sectorId, name),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildStackedBar(Map<int, int> passagesByType, int totalCount, int sectorId, String sectorName) {
|
||||
if (totalCount == 0) {
|
||||
// Barre vide pour les secteurs sans passages
|
||||
return Container(
|
||||
height: 24,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[200],
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Ordre des types : 1, 3, 4, 5, 6, 7, 8, 9, puis 2 en dernier
|
||||
final typeOrder = [1, 3, 4, 5, 6, 7, 8, 9, 2];
|
||||
|
||||
return Container(
|
||||
height: 24,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
border: Border.all(color: Colors.grey[300]!, width: 0.5),
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
child: Stack(
|
||||
children: [
|
||||
// Barre de fond
|
||||
Container(color: Colors.grey[100]),
|
||||
// Barres empilées
|
||||
Row(
|
||||
children: typeOrder.map((typeId) {
|
||||
final count = passagesByType[typeId] ?? 0;
|
||||
if (count == 0) return const SizedBox.shrink();
|
||||
|
||||
final percentage = (count / totalCount) * 100;
|
||||
final typeInfo = AppKeys.typesPassages[typeId];
|
||||
final color = typeInfo != null
|
||||
? Color(typeInfo['couleur2'] as int)
|
||||
: Colors.grey;
|
||||
|
||||
// Vérifier si l'utilisateur est admin pour les clics
|
||||
final bool isAdmin = CurrentUserService.instance.canAccessAdmin;
|
||||
|
||||
return Expanded(
|
||||
flex: count,
|
||||
child: isAdmin
|
||||
? InkWell(
|
||||
onTap: () {
|
||||
// Sauvegarder les filtres dans Hive pour la page historique
|
||||
final settingsBox = Hive.box(AppKeys.settingsBoxName);
|
||||
settingsBox.put('history_selectedSectorId', sectorId);
|
||||
settingsBox.put('history_selectedSectorName', sectorName);
|
||||
settingsBox.put('history_selectedTypeId', typeId);
|
||||
settingsBox.put('adminSelectedPageIndex', 2); // Index de la page historique
|
||||
|
||||
// Naviguer vers le dashboard admin qui chargera la page historique
|
||||
context.go('/admin');
|
||||
},
|
||||
child: Container(
|
||||
color: color,
|
||||
child: Center(
|
||||
child: percentage >= 5 // N'afficher le texte que si >= 5%
|
||||
? Text(
|
||||
'$count (${percentage.toInt()}%)',
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.bold,
|
||||
shadows: [
|
||||
Shadow(
|
||||
offset: Offset(0.5, 0.5),
|
||||
blurRadius: 1.0,
|
||||
color: Colors.black45,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
)
|
||||
: Container(
|
||||
color: color,
|
||||
child: Center(
|
||||
child: percentage >= 5 // N'afficher le texte que si >= 5%
|
||||
? Text(
|
||||
'$count (${percentage.toInt()}%)',
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.bold,
|
||||
shadows: [
|
||||
Shadow(
|
||||
offset: Offset(0.5, 0.5),
|
||||
blurRadius: 1.0,
|
||||
color: Colors.black45,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -216,10 +216,12 @@ class _UserFormState extends State<UserForm> {
|
||||
}
|
||||
}
|
||||
|
||||
// Nettoyer une chaîne pour l'username
|
||||
// Nettoyer une chaîne pour l'username (NIST: garder plus de caractères)
|
||||
String _cleanString(String input) {
|
||||
// Avec NIST, on peut garder plus de caractères, mais pour la génération automatique
|
||||
// on reste sur des caractères simples pour éviter les problèmes
|
||||
return input.toLowerCase()
|
||||
.replaceAll(RegExp(r'[^a-z0-9]'), ''); // Garder seulement lettres et chiffres
|
||||
.replaceAll(RegExp(r'[^a-z0-9\s]'), ''); // Garder lettres, chiffres et espaces
|
||||
}
|
||||
|
||||
// Extraire une partie aléatoire d'une chaîne
|
||||
@@ -235,7 +237,7 @@ class _UserFormState extends State<UserForm> {
|
||||
return cleaned.substring(0, length);
|
||||
}
|
||||
|
||||
// Générer un username selon l'algorithme spécifié
|
||||
// Générer un username selon les nouvelles normes NIST
|
||||
String _generateUsername() {
|
||||
// Récupérer les données nécessaires
|
||||
final nom = _nameController.text.isNotEmpty ? _nameController.text : _sectNameController.text;
|
||||
@@ -248,22 +250,21 @@ class _UserFormState extends State<UserForm> {
|
||||
final villePart = _extractRandomPart(ville, 2, 4);
|
||||
final nombreAleatoire = 10 + _random.nextInt(990); // 10 à 999
|
||||
|
||||
// Choisir des séparateurs aléatoires (uniquement ceux autorisés: ., _, -)
|
||||
final separateurs = ['', '.', '_', '-'];
|
||||
// Choisir des séparateurs aléatoires (on peut maintenant utiliser des espaces aussi)
|
||||
final separateurs = ['', '.', '_', '-', ' '];
|
||||
final sep1 = separateurs[_random.nextInt(separateurs.length)];
|
||||
final sep2 = separateurs[_random.nextInt(separateurs.length)];
|
||||
|
||||
// Assembler l'username
|
||||
String username = '$nomPart$sep1$cpPart$sep2$villePart$nombreAleatoire';
|
||||
|
||||
// Si trop court, ajouter des chiffres pour atteindre minimum 10 caractères
|
||||
while (username.length < 10) {
|
||||
// Si trop court, ajouter des chiffres pour atteindre minimum 8 caractères (NIST)
|
||||
while (username.length < 8) {
|
||||
username += _random.nextInt(10).toString();
|
||||
}
|
||||
|
||||
// S'assurer que l'username ne contient que des caractères autorisés (a-z, 0-9, ., -, _)
|
||||
// Normalement déjà le cas avec notre algorithme, mais au cas où
|
||||
username = username.toLowerCase().replaceAll(RegExp(r'[^a-z0-9._-]'), '');
|
||||
// Avec NIST, on n'a plus besoin de nettoyer les caractères spéciaux
|
||||
// Tous les caractères sont acceptés
|
||||
|
||||
return username;
|
||||
}
|
||||
@@ -341,7 +342,7 @@ class _UserFormState extends State<UserForm> {
|
||||
}
|
||||
}
|
||||
|
||||
// Valider le mot de passe selon les règles
|
||||
// Valider le mot de passe selon les normes NIST SP 800-63B
|
||||
String? _validatePassword(String? value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
// Pour un nouveau membre, le mot de passe est obligatoire si le champ est affiché
|
||||
@@ -351,85 +352,101 @@ class _UserFormState extends State<UserForm> {
|
||||
return null; // En modification, vide = garder l'ancien
|
||||
}
|
||||
|
||||
// Faire un trim pour retirer les espaces en début/fin
|
||||
final trimmedValue = value.trim();
|
||||
if (trimmedValue.isEmpty) {
|
||||
return "Le mot de passe ne peut pas être vide";
|
||||
// Vérifier la longueur minimale (NIST: 8 caractères)
|
||||
if (value.length < 8) {
|
||||
return "Le mot de passe doit contenir au moins 8 caractères";
|
||||
}
|
||||
|
||||
// Vérifier qu'il n'y a pas d'espaces dans le mot de passe
|
||||
if (trimmedValue.contains(' ')) {
|
||||
return "Le mot de passe ne doit pas contenir d'espaces";
|
||||
// Vérifier la longueur maximale (NIST: 64 caractères)
|
||||
if (value.length > 64) {
|
||||
return "Le mot de passe ne doit pas dépasser 64 caractères";
|
||||
}
|
||||
|
||||
// Vérifier la longueur
|
||||
if (trimmedValue.length < 12) {
|
||||
return "Le mot de passe doit contenir au moins 12 caractères";
|
||||
}
|
||||
if (trimmedValue.length > 16) {
|
||||
return "Le mot de passe ne doit pas dépasser 16 caractères";
|
||||
}
|
||||
|
||||
// Vérifier qu'il n'est pas égal au username (après trim des deux)
|
||||
if (trimmedValue == _usernameController.text.trim()) {
|
||||
return "Le mot de passe ne doit pas être identique au nom d'utilisateur";
|
||||
}
|
||||
|
||||
// Vérifier la présence d'au moins une minuscule
|
||||
if (!trimmedValue.contains(RegExp(r'[a-z]'))) {
|
||||
return "Le mot de passe doit contenir au moins une lettre minuscule";
|
||||
}
|
||||
|
||||
// Vérifier la présence d'au moins une majuscule
|
||||
if (!trimmedValue.contains(RegExp(r'[A-Z]'))) {
|
||||
return "Le mot de passe doit contenir au moins une lettre majuscule";
|
||||
}
|
||||
|
||||
// Vérifier la présence d'au moins un chiffre
|
||||
if (!trimmedValue.contains(RegExp(r'[0-9]'))) {
|
||||
return "Le mot de passe doit contenir au moins un chiffre";
|
||||
}
|
||||
|
||||
// Vérifier la présence d'au moins un caractère spécial
|
||||
if (!trimmedValue.contains(RegExp(r'[!@#$%^&*()_+\-=\[\]{}|;:,.<>?]'))) {
|
||||
return "Le mot de passe doit contenir au moins un caractère spécial (!@#\$%^&*()_+-=[]{}|;:,.<>?)";
|
||||
}
|
||||
// NIST: Pas de vérification de composition obligatoire
|
||||
// Les espaces sont autorisés, tous les caractères sont acceptés
|
||||
// L'API vérifiera contre Have I Been Pwned
|
||||
// Pas de vérification password == username (demande client)
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Générer un mot de passe aléatoire respectant les règles
|
||||
// Générer un mot de passe selon les normes NIST (phrases de passe recommandées)
|
||||
String _generatePassword() {
|
||||
const String lowercase = 'abcdefghijklmnopqrstuvwxyz';
|
||||
const String uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
const String digits = '0123456789';
|
||||
const String special = '!@#\$%^&*()_+-=[]{}|;:,.<>?';
|
||||
// Listes de mots pour créer des phrases de passe mémorables
|
||||
final sujets = [
|
||||
'Mon chat', 'Le chien', 'Ma voiture', 'Mon vélo', 'La maison',
|
||||
'Mon jardin', 'Le soleil', 'La lune', 'Mon café', 'Le train',
|
||||
'Ma pizza', 'Le gâteau', 'Mon livre', 'La musique', 'Mon film'
|
||||
];
|
||||
|
||||
// Longueur aléatoire entre 12 et 16
|
||||
final length = 12 + _random.nextInt(5);
|
||||
final noms = [
|
||||
'Félix', 'Max', 'Luna', 'Bella', 'Charlie', 'Rocky', 'Maya',
|
||||
'Oscar', 'Ruby', 'Leo', 'Emma', 'Jack', 'Sophie', 'Milo', 'Zoé'
|
||||
];
|
||||
|
||||
// S'assurer d'avoir au moins un caractère de chaque type
|
||||
List<String> password = [];
|
||||
password.add(lowercase[_random.nextInt(lowercase.length)]);
|
||||
password.add(uppercase[_random.nextInt(uppercase.length)]);
|
||||
password.add(digits[_random.nextInt(digits.length)]);
|
||||
password.add(special[_random.nextInt(special.length)]);
|
||||
final verbes = [
|
||||
'aime', 'mange', 'court', 'saute', 'danse', 'chante', 'joue',
|
||||
'dort', 'rêve', 'vole', 'nage', 'lit', 'écrit', 'peint', 'cuisine'
|
||||
];
|
||||
|
||||
// Compléter avec des caractères aléatoires
|
||||
const String allChars = lowercase + uppercase + digits + special;
|
||||
for (int i = password.length; i < length; i++) {
|
||||
password.add(allChars[_random.nextInt(allChars.length)]);
|
||||
final complements = [
|
||||
'dans le jardin', 'sous la pluie', 'avec joie', 'très vite', 'tout le temps',
|
||||
'en été', 'le matin', 'la nuit', 'au soleil', 'dans la neige',
|
||||
'sur la plage', 'à Paris', 'en vacances', 'avec passion', 'doucement'
|
||||
];
|
||||
|
||||
// Choisir un type de phrase aléatoirement
|
||||
final typePhrase = _random.nextInt(3);
|
||||
String phrase;
|
||||
|
||||
switch (typePhrase) {
|
||||
case 0:
|
||||
// Type: Sujet + nom propre + verbe + complément
|
||||
final sujet = sujets[_random.nextInt(sujets.length)];
|
||||
final nom = noms[_random.nextInt(noms.length)];
|
||||
final verbe = verbes[_random.nextInt(verbes.length)];
|
||||
final complement = complements[_random.nextInt(complements.length)];
|
||||
phrase = '$sujet $nom $verbe $complement';
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// Type: Nom propre + a + nombre + ans + point d'exclamation
|
||||
final nom = noms[_random.nextInt(noms.length)];
|
||||
final age = 1 + _random.nextInt(20);
|
||||
phrase = '$nom a $age ans!';
|
||||
break;
|
||||
|
||||
default:
|
||||
// Type: Sujet + verbe + nombre + complément
|
||||
final sujet = sujets[_random.nextInt(sujets.length)];
|
||||
final verbe = verbes[_random.nextInt(verbes.length)];
|
||||
final nombre = 1 + _random.nextInt(100);
|
||||
final complement = complements[_random.nextInt(complements.length)];
|
||||
phrase = '$sujet $verbe $nombre fois $complement';
|
||||
}
|
||||
|
||||
// Mélanger les caractères
|
||||
password.shuffle(_random);
|
||||
// Ajouter éventuellement un caractère spécial à la fin
|
||||
if (_random.nextBool()) {
|
||||
final speciaux = ['!', '?', '.', '...', '♥', '☀', '★', '♪'];
|
||||
phrase += speciaux[_random.nextInt(speciaux.length)];
|
||||
}
|
||||
|
||||
return password.join('');
|
||||
// S'assurer que la phrase fait au moins 8 caractères (elle le sera presque toujours)
|
||||
if (phrase.length < 8) {
|
||||
phrase += ' ${1000 + _random.nextInt(9000)}';
|
||||
}
|
||||
|
||||
// Tronquer si trop long (max 64 caractères selon NIST)
|
||||
if (phrase.length > 64) {
|
||||
phrase = phrase.substring(0, 64);
|
||||
}
|
||||
|
||||
return phrase;
|
||||
}
|
||||
|
||||
// Méthode publique pour récupérer le mot de passe si défini
|
||||
String? getPassword() {
|
||||
final password = _passwordController.text.trim();
|
||||
final password = _passwordController.text; // NIST: ne pas faire de trim, les espaces sont autorisés
|
||||
return password.isNotEmpty ? password : null;
|
||||
}
|
||||
|
||||
@@ -437,7 +454,7 @@ class _UserFormState extends State<UserForm> {
|
||||
UserModel? validateAndGetUser() {
|
||||
if (_formKey.currentState!.validate()) {
|
||||
return widget.user?.copyWith(
|
||||
username: _usernameController.text.trim(), // Appliquer trim
|
||||
username: _usernameController.text, // NIST: ne pas faire de trim sur username
|
||||
firstName: _firstNameController.text.trim(),
|
||||
name: _nameController.text.trim(),
|
||||
sectName: _sectNameController.text.trim(),
|
||||
@@ -450,7 +467,7 @@ class _UserFormState extends State<UserForm> {
|
||||
) ??
|
||||
UserModel(
|
||||
id: 0,
|
||||
username: _usernameController.text.trim(), // Appliquer trim
|
||||
username: _usernameController.text, // NIST: ne pas faire de trim sur username
|
||||
firstName: _firstNameController.text.trim(),
|
||||
name: _nameController.text.trim(),
|
||||
sectName: _sectNameController.text.trim(),
|
||||
@@ -729,30 +746,23 @@ class _UserFormState extends State<UserForm> {
|
||||
)
|
||||
: null,
|
||||
helperText: canEditUsername
|
||||
? "Min. 10 caractères (a-z, 0-9, . - _)"
|
||||
? "8 à 64 caractères. Tous les caractères sont acceptés, y compris les espaces et accents."
|
||||
: null,
|
||||
helperMaxLines: 2,
|
||||
validator: canEditUsername
|
||||
? (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return "Veuillez entrer le nom d'utilisateur";
|
||||
}
|
||||
// Faire un trim pour retirer les espaces en début/fin
|
||||
final trimmedValue = value.trim();
|
||||
if (trimmedValue.isEmpty) {
|
||||
return "Le nom d'utilisateur ne peut pas être vide";
|
||||
// Vérifier la longueur minimale (NIST: 8 caractères)
|
||||
if (value.length < 8) {
|
||||
return "Le nom d'utilisateur doit contenir au moins 8 caractères";
|
||||
}
|
||||
// Vérifier qu'il n'y a pas d'espaces dans l'username
|
||||
if (trimmedValue.contains(' ')) {
|
||||
return "Le nom d'utilisateur ne doit pas contenir d'espaces";
|
||||
}
|
||||
// Vérifier la longueur minimale
|
||||
if (trimmedValue.length < 10) {
|
||||
return "Le nom d'utilisateur doit contenir au moins 10 caractères";
|
||||
}
|
||||
// Vérifier les caractères autorisés (a-z, 0-9, ., -, _)
|
||||
if (!RegExp(r'^[a-z0-9._-]+$').hasMatch(trimmedValue)) {
|
||||
return "Caractères autorisés : lettres minuscules, chiffres, . - _";
|
||||
// Vérifier la longueur maximale (NIST: 64 caractères)
|
||||
if (value.length > 64) {
|
||||
return "Le nom d'utilisateur ne doit pas dépasser 64 caractères";
|
||||
}
|
||||
// Pas de vérification sur le type de caractères (NIST: tous acceptés)
|
||||
return null;
|
||||
}
|
||||
: null,
|
||||
@@ -800,7 +810,8 @@ class _UserFormState extends State<UserForm> {
|
||||
),
|
||||
helperText: widget.user?.id != 0
|
||||
? "Laissez vide pour conserver le mot de passe actuel"
|
||||
: "12-16 car. avec min/maj, chiffres et spéciaux (!@#\$%^&*()_+-=[]{}|;:,.<>?)",
|
||||
: "8 à 64 caractères. Phrases de passe recommandées (ex: Mon chat Félix a 3 ans!)",
|
||||
helperMaxLines: 3,
|
||||
validator: _validatePassword,
|
||||
),
|
||||
),
|
||||
@@ -837,30 +848,23 @@ class _UserFormState extends State<UserForm> {
|
||||
)
|
||||
: null,
|
||||
helperText: canEditUsername
|
||||
? "Min. 10 caractères (a-z, 0-9, . - _)"
|
||||
? "8 à 64 caractères. Tous les caractères sont acceptés, y compris les espaces et accents."
|
||||
: null,
|
||||
helperMaxLines: 2,
|
||||
validator: canEditUsername
|
||||
? (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return "Veuillez entrer le nom d'utilisateur";
|
||||
}
|
||||
// Faire un trim pour retirer les espaces en début/fin
|
||||
final trimmedValue = value.trim();
|
||||
if (trimmedValue.isEmpty) {
|
||||
return "Le nom d'utilisateur ne peut pas être vide";
|
||||
// Vérifier la longueur minimale (NIST: 8 caractères)
|
||||
if (value.length < 8) {
|
||||
return "Le nom d'utilisateur doit contenir au moins 8 caractères";
|
||||
}
|
||||
// Vérifier qu'il n'y a pas d'espaces dans l'username
|
||||
if (trimmedValue.contains(' ')) {
|
||||
return "Le nom d'utilisateur ne doit pas contenir d'espaces";
|
||||
}
|
||||
// Vérifier la longueur minimale
|
||||
if (trimmedValue.length < 10) {
|
||||
return "Le nom d'utilisateur doit contenir au moins 10 caractères";
|
||||
}
|
||||
// Vérifier les caractères autorisés (a-z, 0-9, ., -, _)
|
||||
if (!RegExp(r'^[a-z0-9._-]+$').hasMatch(trimmedValue)) {
|
||||
return "Caractères autorisés : lettres minuscules, chiffres, . - _";
|
||||
// Vérifier la longueur maximale (NIST: 64 caractères)
|
||||
if (value.length > 64) {
|
||||
return "Le nom d'utilisateur ne doit pas dépasser 64 caractères";
|
||||
}
|
||||
// Pas de vérification sur le type de caractères (NIST: tous acceptés)
|
||||
return null;
|
||||
}
|
||||
: null,
|
||||
@@ -906,7 +910,8 @@ class _UserFormState extends State<UserForm> {
|
||||
),
|
||||
helperText: widget.user?.id != 0
|
||||
? "Laissez vide pour conserver le mot de passe actuel"
|
||||
: "12-16 car. avec min/maj, chiffres et spéciaux (!@#\$%^&*()_+-=[]{}|;:,.<>?)",
|
||||
: "8 à 64 caractères. Phrases de passe recommandées (ex: Mon chat Félix a 3 ans!)",
|
||||
helperMaxLines: 3,
|
||||
validator: _validatePassword,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
@@ -1 +1 @@
|
||||
/home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.4/
|
||||
/home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/
|
||||
@@ -1 +1 @@
|
||||
/home/pierre/.pub-cache/hosted/pub.dev/package_info_plus-8.3.0/
|
||||
/home/pierre/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/
|
||||
@@ -3,8 +3,8 @@ FLUTTER_ROOT=/home/pierre/dev/flutter
|
||||
FLUTTER_APPLICATION_PATH=/home/pierre/dev/geosector/app
|
||||
COCOAPODS_PARALLEL_CODE_SIGN=true
|
||||
FLUTTER_BUILD_DIR=build
|
||||
FLUTTER_BUILD_NAME=3.0.6
|
||||
FLUTTER_BUILD_NUMBER=306
|
||||
FLUTTER_BUILD_NAME=3.0.8
|
||||
FLUTTER_BUILD_NUMBER=308
|
||||
DART_OBFUSCATION=false
|
||||
TRACK_WIDGET_CREATION=true
|
||||
TREE_SHAKE_ICONS=false
|
||||
|
||||
@@ -4,8 +4,8 @@ export "FLUTTER_ROOT=/home/pierre/dev/flutter"
|
||||
export "FLUTTER_APPLICATION_PATH=/home/pierre/dev/geosector/app"
|
||||
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
|
||||
export "FLUTTER_BUILD_DIR=build"
|
||||
export "FLUTTER_BUILD_NAME=3.0.6"
|
||||
export "FLUTTER_BUILD_NUMBER=306"
|
||||
export "FLUTTER_BUILD_NAME=3.0.8"
|
||||
export "FLUTTER_BUILD_NUMBER=308"
|
||||
export "DART_OBFUSCATION=false"
|
||||
export "TRACK_WIDGET_CREATION=true"
|
||||
export "TREE_SHAKE_ICONS=false"
|
||||
|
||||
@@ -178,10 +178,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: connectivity_plus
|
||||
sha256: "051849e2bd7c7b3bc5844ea0d096609ddc3a859890ec3a9ac4a65a2620cc1f99"
|
||||
sha256: b5e72753cf63becce2c61fd04dfe0f1c430cc5278b53a1342dc5ad839eab29ec
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.1.4"
|
||||
version: "6.1.5"
|
||||
connectivity_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -718,10 +718,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_platform_interface
|
||||
sha256: "886d57f0be73c4b140004e78b9f28a8914a09e50c2d816bdd0520051a71236a0"
|
||||
sha256: "9f143b0dba3e459553209e20cc425c9801af48e6dfa4f01a0fcf927be3f41665"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.10.1"
|
||||
version: "2.11.0"
|
||||
image_picker_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -878,10 +878,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: mqtt5_client
|
||||
sha256: ab00c8acf6aa1440068c8c6fbd604466571f344de15e1997764c1a67477cf01b
|
||||
sha256: d05b57241deb5b78302def74f2c5fc7a7f911ccc6fcb95fa3c51df65ef312d1d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.13.3"
|
||||
version: "4.14.0"
|
||||
nm:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -902,18 +902,18 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: package_info_plus
|
||||
sha256: "7976bfe4c583170d6cdc7077e3237560b364149fcd268b5f53d95a991963b191"
|
||||
sha256: "16eee997588c60225bda0488b6dcfac69280a6b7a3cf02c741895dd370a02968"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.3.0"
|
||||
version: "8.3.1"
|
||||
package_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_info_plus_platform_interface
|
||||
sha256: "6c935fb612dff8e3cc9632c2b301720c77450a126114126ffaafe28d2e87956c"
|
||||
sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.0"
|
||||
version: "3.2.1"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1195,18 +1195,18 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: syncfusion_flutter_charts
|
||||
sha256: a2263d6221b17d49ea9c23709df8796abde4cd2d2664960d48fac62b9d8c3eb8
|
||||
sha256: bb9587289be96520c1808de8bc95b08acc80e6a3a733fcc70f669885fbab4336
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "30.2.4"
|
||||
version: "30.2.5"
|
||||
syncfusion_flutter_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: syncfusion_flutter_core
|
||||
sha256: "9d6b7722331e8c84e837d852da03f3735bf436fe6ebf2acc3455a2a21a0d47ff"
|
||||
sha256: ce02ce65f51db8e29edc9d2225872d927e001bd2b13c2490d176563bbb046fc7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "30.2.4"
|
||||
version: "30.2.5"
|
||||
synchronized:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: geosector_app
|
||||
description: 'GEOSECTOR - Gestion de distribution des calendriers par secteurs géographiques pour les amicales de pompiers'
|
||||
publish_to: 'none'
|
||||
version: 3.0.6+306
|
||||
version: 3.0.8+308
|
||||
|
||||
environment:
|
||||
sdk: '>=3.0.0 <4.0.0'
|
||||
|
||||
295
app/tests-android.md
Normal file
295
app/tests-android.md
Normal file
@@ -0,0 +1,295 @@
|
||||
# 📱 Guide de Test Mobile - Geosector App
|
||||
|
||||
## 🚀 Configuration Rapide
|
||||
|
||||
### 1️⃣ Préparation du Mobile Android
|
||||
|
||||
#### Activer le Mode Développeur
|
||||
```
|
||||
Paramètres → À propos du téléphone → Tapoter 7 fois sur "Numéro de build"
|
||||
```
|
||||
|
||||
#### Activer les Options de Développement
|
||||
```
|
||||
Paramètres → Options pour les développeurs → Activer :
|
||||
✅ Options pour les développeurs
|
||||
✅ Débogage USB
|
||||
✅ Débogage sans fil (pour WiFi)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔌 Test via USB
|
||||
|
||||
### Connexion USB
|
||||
1. Brancher le téléphone en USB-C
|
||||
2. Accepter l'autorisation de débogage sur le téléphone
|
||||
|
||||
### Commandes Terminal
|
||||
```bash
|
||||
# Vérifier la connexion
|
||||
adb devices
|
||||
flutter devices
|
||||
|
||||
# Lancer l'app (mode debug avec hot reload)
|
||||
flutter run
|
||||
|
||||
# Lancer l'app sur un appareil spécifique
|
||||
flutter run -d [DEVICE_ID]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📶 Test via WiFi (Sans Fil)
|
||||
|
||||
### Configuration sur le Mobile
|
||||
1. **Activer le Débogage sans fil** dans Options pour les développeurs
|
||||
2. **Entrer dans "Débogage sans fil"** et noter :
|
||||
- Nom de l'appareil (ex: Pi25)
|
||||
- Adresse IP et port (ex: 192.168.1.103:33503)
|
||||
|
||||
### Première Connexion (avec code d'association)
|
||||
```bash
|
||||
# Si première connexion, associer avec code
|
||||
# Sur mobile : "Associer l'appareil avec un code d'association"
|
||||
adb pair [IP:PORT_ASSOCIATION] [CODE_6_CHIFFRES]
|
||||
# Exemple : adb pair 192.168.1.103:37953 123456
|
||||
```
|
||||
|
||||
### Connexion Standard
|
||||
```bash
|
||||
# Connecter via WiFi
|
||||
adb connect [IP:PORT]
|
||||
# Exemple : adb connect 192.168.1.103:33503
|
||||
|
||||
# Vérifier la connexion
|
||||
adb devices
|
||||
flutter devices
|
||||
|
||||
# Lancer l'app
|
||||
flutter run -d [IP:PORT]
|
||||
# Exemple : flutter run -d 192.168.1.103:33503
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Modes de Compilation
|
||||
|
||||
### Mode Debug (Développement)
|
||||
```bash
|
||||
# Avec hot reload, logs complets, banner DEBUG
|
||||
flutter run
|
||||
flutter run -d [DEVICE_ID]
|
||||
```
|
||||
|
||||
**Raccourcis pendant l'exécution :**
|
||||
- `r` : Hot reload (rechargement rapide)
|
||||
- `R` : Hot restart (redémarrage complet)
|
||||
- `p` : Afficher le widget tree
|
||||
- `o` : Basculer Android/iOS preview
|
||||
- `q` : Quitter
|
||||
|
||||
### Mode Release (Performance)
|
||||
```bash
|
||||
# Optimisé, rapide, sans debug
|
||||
flutter run --release
|
||||
flutter run -d [DEVICE_ID] --release
|
||||
```
|
||||
|
||||
### Mode Profile (Analyse)
|
||||
```bash
|
||||
# Pour profiler les performances
|
||||
flutter run --profile
|
||||
flutter run -d [DEVICE_ID] --profile
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📦 Build et Installation
|
||||
|
||||
### Créer l'APK
|
||||
```bash
|
||||
# APK standard
|
||||
flutter build apk
|
||||
|
||||
# APK optimisé pour release
|
||||
flutter build apk --release
|
||||
|
||||
# APK avec obfuscation
|
||||
flutter build apk --release --obfuscate --split-debug-info=debug_info
|
||||
|
||||
# APK split par architecture (plus petit)
|
||||
flutter build apk --split-per-abi
|
||||
```
|
||||
|
||||
### Installer l'APK
|
||||
```bash
|
||||
# Installer sur appareil connecté
|
||||
flutter install
|
||||
flutter install -d [DEVICE_ID]
|
||||
|
||||
# Installer un APK spécifique
|
||||
adb install build/app/outputs/flutter-apk/app-release.apk
|
||||
```
|
||||
|
||||
### Bundle pour Play Store
|
||||
```bash
|
||||
flutter build appbundle --release
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Commandes Utiles
|
||||
|
||||
### Gestion des Appareils
|
||||
```bash
|
||||
# Lister tous les appareils
|
||||
flutter devices
|
||||
|
||||
# Infos détaillées ADB
|
||||
adb devices -l
|
||||
|
||||
# Déconnecter un appareil WiFi
|
||||
adb disconnect [IP:PORT]
|
||||
|
||||
# Redémarrer ADB
|
||||
adb kill-server
|
||||
adb start-server
|
||||
```
|
||||
|
||||
### Nettoyage et Réparation
|
||||
```bash
|
||||
# Nettoyer le projet
|
||||
flutter clean
|
||||
|
||||
# Réinstaller les dépendances
|
||||
flutter pub get
|
||||
|
||||
# Régénérer les fichiers
|
||||
flutter pub run build_runner build --delete-conflicting-outputs
|
||||
|
||||
# Vérifier l'installation Flutter
|
||||
flutter doctor
|
||||
```
|
||||
|
||||
### Logs et Débogage
|
||||
```bash
|
||||
# Voir les logs du téléphone
|
||||
adb logcat
|
||||
|
||||
# Logs Flutter uniquement
|
||||
flutter logs
|
||||
|
||||
# Capturer une capture d'écran
|
||||
adb shell screencap -p /sdcard/screenshot.png
|
||||
adb pull /sdcard/screenshot.png
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📱 Tests sur le Mobile
|
||||
|
||||
### Vérifications Visuelles
|
||||
- [ ] **AppBar** : Logo Geosector + Logo Amicale (si disponible)
|
||||
- [ ] **Navigation** :
|
||||
- Admin : Bordure rouge, menu sélectionné en rouge/gras
|
||||
- User : Bordure verte, menu sélectionné en vert/gras
|
||||
- [ ] **Menu Mobile** : Icônes uniquement en bas (sans texte)
|
||||
- [ ] **Responsive** : Adaptation portrait/paysage
|
||||
|
||||
### Tests Fonctionnels
|
||||
- [ ] Connexion/Déconnexion
|
||||
- [ ] Navigation entre les pages
|
||||
- [ ] Formulaires et validations
|
||||
- [ ] Synchronisation des données
|
||||
- [ ] Mode hors-ligne
|
||||
|
||||
### Performance
|
||||
- [ ] Temps de chargement
|
||||
- [ ] Fluidité du scroll
|
||||
- [ ] Réactivité des boutons
|
||||
- [ ] Consommation mémoire
|
||||
|
||||
---
|
||||
|
||||
## 🆘 Résolution de Problèmes
|
||||
|
||||
### Appareil Non Détecté
|
||||
```bash
|
||||
# Vérifier les drivers USB
|
||||
adb devices
|
||||
|
||||
# Relancer ADB
|
||||
adb kill-server
|
||||
adb start-server
|
||||
|
||||
# Vérifier Flutter
|
||||
flutter doctor -v
|
||||
```
|
||||
|
||||
### Erreur de Connexion WiFi
|
||||
```bash
|
||||
# Vérifier le réseau (même WiFi PC et mobile)
|
||||
ping [IP_MOBILE]
|
||||
|
||||
# Réassocier l'appareil
|
||||
adb pair [IP:PORT] [CODE]
|
||||
|
||||
# Forcer la reconnexion
|
||||
adb disconnect
|
||||
adb connect [IP:PORT]
|
||||
```
|
||||
|
||||
### Build Échoué
|
||||
```bash
|
||||
# Nettoyer et reconstruire
|
||||
flutter clean
|
||||
flutter pub get
|
||||
flutter run
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💡 Tips & Astuces
|
||||
|
||||
1. **Gardez le téléphone déverrouillé** pendant les tests
|
||||
2. **Désactivez l'économie d'énergie** pour éviter les déconnexions
|
||||
3. **Utilisez le mode Release** pour tester les vraies performances
|
||||
4. **Activez "Rester éveillé"** dans Options développeur
|
||||
5. **WiFi stable** : Préférez le 5GHz au 2.4GHz si disponible
|
||||
|
||||
---
|
||||
|
||||
## 📊 Exemple de Session Type
|
||||
|
||||
```bash
|
||||
# 1. Connexion WiFi
|
||||
adb connect 192.168.1.103:33503
|
||||
|
||||
# 2. Vérification
|
||||
flutter devices
|
||||
|
||||
# 3. Lancement en debug
|
||||
flutter run -d 192.168.1.103:33503
|
||||
|
||||
# 4. Tests et hot reload (touche r)
|
||||
|
||||
# 5. Test performance
|
||||
flutter run -d 192.168.1.103:33503 --release
|
||||
|
||||
# 6. Build final
|
||||
flutter build apk --release
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 Notes Spécifiques Geosector
|
||||
|
||||
- **Environnement** : L'app détecte automatiquement DEV/REC/PROD
|
||||
- **Logos** : Le logo amicale s'affiche si disponible en base64
|
||||
- **Rôles** : Admin (rouge) vs User (vert) dans l'interface
|
||||
- **Cache** : Utilise Hive pour le stockage local
|
||||
|
||||
---
|
||||
|
||||
*Guide créé pour Geosector v3.0.6 - Flutter 3.32+*
|
||||
385
app/tests-iphone.md
Normal file
385
app/tests-iphone.md
Normal file
@@ -0,0 +1,385 @@
|
||||
# 📱 Guide de Test iOS - Geosector App
|
||||
|
||||
## ⚠️ Prérequis Importants
|
||||
|
||||
### Matériel Requis
|
||||
- **Mac** avec macOS 10.15 (Catalina) ou plus récent
|
||||
- **iPhone** avec iOS 12.0 ou plus récent
|
||||
- **Câble Lightning/USB-C** pour la connexion
|
||||
- **Apple Developer Account** (gratuit pour tests locaux)
|
||||
- **Xcode** 14.0 ou plus récent
|
||||
|
||||
### ❌ Limitations Linux/Windows
|
||||
**IMPORTANT** : Le développement iOS nécessite obligatoirement un Mac.
|
||||
- Pas de compilation iOS native sur Linux/Windows
|
||||
- Solutions alternatives limitées (voir section "Alternatives")
|
||||
|
||||
---
|
||||
|
||||
## 🍎 Configuration sur Mac
|
||||
|
||||
### 1️⃣ Installation des Outils
|
||||
|
||||
#### Installer Xcode
|
||||
```bash
|
||||
# Via App Store ou ligne de commande
|
||||
xcode-select --install
|
||||
|
||||
# Accepter la licence Xcode
|
||||
sudo xcodebuild -license accept
|
||||
```
|
||||
|
||||
#### Vérifier Flutter pour iOS
|
||||
```bash
|
||||
# Vérifier la configuration iOS
|
||||
flutter doctor
|
||||
|
||||
# Résoudre les problèmes iOS si nécessaire
|
||||
flutter doctor --verbose
|
||||
```
|
||||
|
||||
#### Installer CocoaPods
|
||||
```bash
|
||||
# CocoaPods est nécessaire pour les dépendances iOS
|
||||
sudo gem install cocoapods
|
||||
pod setup
|
||||
```
|
||||
|
||||
### 2️⃣ Configuration du Projet
|
||||
|
||||
#### Ouvrir le projet iOS dans Xcode
|
||||
```bash
|
||||
# Depuis le dossier du projet Flutter
|
||||
cd ios
|
||||
open Runner.xcworkspace
|
||||
```
|
||||
|
||||
#### Configuration dans Xcode
|
||||
1. **Sélectionner l'équipe de développement** :
|
||||
- Runner → Signing & Capabilities
|
||||
- Team : Sélectionner votre Apple ID
|
||||
- Bundle Identifier : `com.votredomaine.geosector`
|
||||
|
||||
2. **Configurer le déploiement** :
|
||||
- Deployment Info → iOS 12.0 minimum
|
||||
- Device Orientation : Portrait + Landscape
|
||||
|
||||
---
|
||||
|
||||
## 📲 Configuration de l'iPhone
|
||||
|
||||
### 1️⃣ Mode Développeur (iOS 16+)
|
||||
|
||||
#### Activer le Mode Développeur
|
||||
```
|
||||
Réglages → Confidentialité et sécurité → Mode développeur → Activer
|
||||
```
|
||||
**Note** : Le téléphone redémarrera
|
||||
|
||||
### 2️⃣ Trust Computer
|
||||
|
||||
1. Brancher l'iPhone au Mac
|
||||
2. **Sur l'iPhone** : "Faire confiance à cet ordinateur" → Faire confiance
|
||||
3. Entrer le code de déverrouillage
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Lancer l'Application
|
||||
|
||||
### Test via USB
|
||||
|
||||
#### Vérifier la connexion
|
||||
```bash
|
||||
# Lister les appareils disponibles
|
||||
flutter devices
|
||||
|
||||
# Devrait afficher quelque chose comme :
|
||||
# iPhone de Pierre (mobile) • 00008110-001234567890ABCD • ios • iOS 17.2
|
||||
```
|
||||
|
||||
#### Lancer en mode Debug
|
||||
```bash
|
||||
# Lancer sur l'iPhone connecté
|
||||
flutter run
|
||||
|
||||
# Ou spécifier l'appareil
|
||||
flutter run -d [DEVICE_ID]
|
||||
```
|
||||
|
||||
#### Lancer en mode Release
|
||||
```bash
|
||||
# Performance optimale
|
||||
flutter run --release
|
||||
|
||||
# Avec l'ID de l'appareil
|
||||
flutter run -d [DEVICE_ID] --release
|
||||
```
|
||||
|
||||
### Test via WiFi (Xcode 9+)
|
||||
|
||||
#### Configuration WiFi
|
||||
1. **iPhone et Mac** sur le même réseau WiFi
|
||||
2. Dans **Xcode** : Window → Devices and Simulators
|
||||
3. Sélectionner l'iPhone → Cocher "Connect via network"
|
||||
4. Débrancher le câble USB
|
||||
|
||||
#### Lancer via WiFi
|
||||
```bash
|
||||
# L'appareil reste visible dans flutter devices
|
||||
flutter run -d [DEVICE_ID]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Build et Installation
|
||||
|
||||
### Créer l'Archive iOS
|
||||
|
||||
#### Build pour App Store Connect
|
||||
```bash
|
||||
# Nettoyer le projet
|
||||
flutter clean
|
||||
cd ios && pod install && cd ..
|
||||
|
||||
# Build release
|
||||
flutter build ios --release
|
||||
|
||||
# Ou avec obfuscation
|
||||
flutter build ios --release --obfuscate --split-debug-info=debug_info
|
||||
```
|
||||
|
||||
#### Archive dans Xcode
|
||||
1. Ouvrir `ios/Runner.xcworkspace` dans Xcode
|
||||
2. Product → Scheme → Runner
|
||||
3. Product → Destination → Any iOS Device
|
||||
4. Product → Archive
|
||||
5. Distribute App → Ad Hoc ou App Store
|
||||
|
||||
### Installation via TestFlight
|
||||
|
||||
#### Configuration TestFlight
|
||||
1. Upload l'archive vers **App Store Connect**
|
||||
2. Ajouter les testeurs (emails)
|
||||
3. Les testeurs reçoivent une invitation
|
||||
|
||||
#### Installation sur iPhone
|
||||
1. Installer l'app **TestFlight** depuis l'App Store
|
||||
2. Accepter l'invitation (via email)
|
||||
3. Installer l'app Geosector depuis TestFlight
|
||||
|
||||
---
|
||||
|
||||
## 📱 Simulateur iOS
|
||||
|
||||
### Lancer sur Simulateur
|
||||
```bash
|
||||
# Lister les simulateurs disponibles
|
||||
flutter emulators
|
||||
|
||||
# Lancer un simulateur
|
||||
flutter emulators --launch apple_ios_simulator
|
||||
|
||||
# Ou ouvrir via Xcode
|
||||
open -a Simulator
|
||||
|
||||
# Lancer l'app sur le simulateur
|
||||
flutter run
|
||||
```
|
||||
|
||||
### Simulateurs Recommandés
|
||||
- iPhone 15 Pro (dernier modèle)
|
||||
- iPhone SE (petit écran)
|
||||
- iPad Pro (tablette)
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Commandes Utiles iOS
|
||||
|
||||
### Gestion des Certificats
|
||||
```bash
|
||||
# Vérifier les certificats
|
||||
security find-identity -p codesigning -v
|
||||
|
||||
# Nettoyer le cache DerivedData
|
||||
rm -rf ~/Library/Developer/Xcode/DerivedData
|
||||
```
|
||||
|
||||
### Pods et Dépendances
|
||||
```bash
|
||||
# Mettre à jour les pods
|
||||
cd ios
|
||||
pod update
|
||||
pod install --repo-update
|
||||
|
||||
# Nettoyer les pods
|
||||
pod deintegrate
|
||||
pod install
|
||||
```
|
||||
|
||||
### Logs et Debug
|
||||
```bash
|
||||
# Voir les logs de l'iPhone
|
||||
flutter logs
|
||||
|
||||
# Console Xcode pour logs détaillés
|
||||
# Xcode → Window → Devices and Simulators → View Device Logs
|
||||
|
||||
# Logs système iOS
|
||||
xcrun simctl spawn booted log stream --level debug
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Résolution de Problèmes
|
||||
|
||||
### Erreur "Could not find Developer Disk Image"
|
||||
```bash
|
||||
# Mettre à jour Xcode pour supporter la version iOS
|
||||
# Ou télécharger les Developer Disk Images
|
||||
```
|
||||
|
||||
### Erreur de Signature
|
||||
```bash
|
||||
# Dans Xcode
|
||||
# Runner → Build Settings → Code Signing Identity → Apple Development
|
||||
# Runner → Signing & Capabilities → Automatically manage signing
|
||||
```
|
||||
|
||||
### Erreur CocoaPods
|
||||
```bash
|
||||
cd ios
|
||||
pod cache clean --all
|
||||
rm -rf Pods
|
||||
rm Podfile.lock
|
||||
pod install
|
||||
```
|
||||
|
||||
### Application Non Fiable
|
||||
```
|
||||
iPhone → Réglages → Général → VPN et gestion d'appareils
|
||||
→ App du développeur → Faire confiance
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Tests Spécifiques iOS
|
||||
|
||||
### Vérifications Visuelles
|
||||
- [ ] **Safe Area** : Respect des encoches (notch)
|
||||
- [ ] **Gestes iOS** : Swipe pour retour arrière
|
||||
- [ ] **Dark Mode** : Adaptation au thème système
|
||||
- [ ] **Dynamic Type** : Respect des tailles de texte système
|
||||
|
||||
### Permissions iOS
|
||||
- [ ] **Localisation** : Demande d'autorisation
|
||||
- [ ] **Notifications** : Permission push (si applicable)
|
||||
- [ ] **Caméra** : Accès pour scan (si applicable)
|
||||
|
||||
### Performance
|
||||
- [ ] **Démarrage** : Temps de lancement < 2s
|
||||
- [ ] **Animations** : 60 FPS constant
|
||||
- [ ] **Mémoire** : Pas de fuites (Instruments)
|
||||
- [ ] **Batterie** : Consommation raisonnable
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Alternatives sans Mac
|
||||
|
||||
### 1. Codemagic CI/CD
|
||||
```yaml
|
||||
# codemagic.yaml
|
||||
workflows:
|
||||
ios-workflow:
|
||||
name: iOS Build
|
||||
environment:
|
||||
xcode: latest
|
||||
scripts:
|
||||
- flutter build ios --release
|
||||
```
|
||||
|
||||
### 2. GitHub Actions
|
||||
```yaml
|
||||
# .github/workflows/ios.yml
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: subosito/flutter-action@v2
|
||||
- run: flutter build ios --release --no-codesign
|
||||
```
|
||||
|
||||
### 3. Services Cloud
|
||||
- **MacinCloud** : Location de Mac virtuel
|
||||
- **MacStadium** : Mac en cloud
|
||||
- **AWS EC2 Mac** : Instances Mac sur AWS
|
||||
|
||||
### 4. Hackintosh (Non Recommandé)
|
||||
⚠️ **Risques** :
|
||||
- Violation des conditions Apple
|
||||
- Instabilité système
|
||||
- Pas de support officiel
|
||||
|
||||
---
|
||||
|
||||
## 📋 Checklist Pré-Release iOS
|
||||
|
||||
### Configuration
|
||||
- [ ] Bundle ID unique configuré
|
||||
- [ ] Icônes de l'app (toutes tailles)
|
||||
- [ ] Launch Screen configuré
|
||||
- [ ] Info.plist à jour
|
||||
- [ ] Permissions déclarées
|
||||
|
||||
### Tests
|
||||
- [ ] Test sur iPhone réel
|
||||
- [ ] Test sur iPad (si supporté)
|
||||
- [ ] Test iOS minimum (12.0)
|
||||
- [ ] Test iOS récent (17.x)
|
||||
- [ ] Test mode avion
|
||||
|
||||
### App Store
|
||||
- [ ] Screenshots (toutes tailles)
|
||||
- [ ] Description de l'app
|
||||
- [ ] Mots-clés optimisés
|
||||
- [ ] Catégorie appropriée
|
||||
- [ ] Politique de confidentialité
|
||||
|
||||
---
|
||||
|
||||
## 💡 Tips iOS
|
||||
|
||||
1. **Provisioning Profile** : Renouveler tous les ans
|
||||
2. **TestFlight** : Builds expirent après 90 jours
|
||||
3. **App Store Review** : Prévoir 24-48h de délai
|
||||
4. **Crash Reports** : Utiliser Crashlytics ou Sentry
|
||||
5. **Push Notifications** : Nécessite certificat APNS
|
||||
|
||||
---
|
||||
|
||||
## 📊 Commandes Rapides
|
||||
|
||||
```bash
|
||||
# Session de test typique sur Mac
|
||||
flutter clean
|
||||
cd ios && pod install && cd ..
|
||||
flutter devices
|
||||
flutter run -d [iPhone_ID]
|
||||
|
||||
# Build pour distribution
|
||||
flutter build ios --release
|
||||
open ios/Runner.xcworkspace
|
||||
# Product → Archive dans Xcode
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🆘 Support
|
||||
|
||||
- **Documentation Flutter iOS** : https://flutter.dev/docs/deployment/ios
|
||||
- **Apple Developer** : https://developer.apple.com
|
||||
- **Forums Flutter** : https://github.com/flutter/flutter/issues
|
||||
|
||||
---
|
||||
|
||||
*Guide créé pour Geosector v3.0.6 - Flutter 3.32+ - iOS 12.0+*
|
||||
|
||||
**Note importante** : Ce guide nécessite un Mac pour la compilation et le déploiement iOS. Pour tester depuis Linux/Windows, utilisez les services cloud ou CI/CD mentionnés.
|
||||
@@ -1 +1 @@
|
||||
/home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.4/
|
||||
/home/pierre/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/
|
||||
@@ -1 +1 @@
|
||||
/home/pierre/.pub-cache/hosted/pub.dev/package_info_plus-8.3.0/
|
||||
/home/pierre/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/
|
||||
Reference in New Issue
Block a user