Skip to content

Instantly share code, notes, and snippets.

@roipeker
Last active April 15, 2021 08:57
Show Gist options
  • Save roipeker/2ac7575bcff374bd170a125b916c8b41 to your computer and use it in GitHub Desktop.
Save roipeker/2ac7575bcff374bd170a125b916c8b41 to your computer and use it in GitHub Desktop.
GetX: button with loading state
/// LIVE DEMO: https://dartpad.dev/embed-flutter.html?theme=dark&id=2ac7575bcff374bd170a125b916c8b41
import 'dart:developer' as developer; import 'dart:async'; import 'dart:collection'; import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/scheduler.dart'; import 'dart:math' as math; import 'dart:ui' as ui; import 'dart:typed_data'; import 'dart:convert';
// ignore: avoid_web_libraries_in_flutter
import 'dart:html' as html;
import 'package:flutter/material.dart';
class ButtonController extends GetxController {
static const kColorOut = Color(0xff2C2C2C);
static const kColorOver = Color(0xff464646);
final isLoading = false.obs;
final isOver = false.obs;
CrossFadeState fadeState = CrossFadeState.showFirst;
double w = 130, h = 46, radius = 13;
Worker _worker;
Color get backgroundColor => isOver() ? kColorOver : kColorOut;
@override
void onInit() {
super.onInit();
_worker = ever(isLoading, (flag) => flag ? _toLoading() : _toButton());
}
@override
void onClose() {
super.onClose();
_worker?.dispose();
}
void _toLoading() {
w = 46;
h = 46;
radius = 23;
fadeState = CrossFadeState.showSecond;
}
void _toButton() {
w = 130;
h = 46;
radius = 13;
fadeState = CrossFadeState.showFirst;
}
void toggleAnimation() => isLoading.toggle();
}
class ButtonLoader extends GetView<ButtonController> {
final labelStyle = TextStyle(
color: Color(0xffFDFDFD),
fontSize: 15,
letterSpacing: .05,
fontWeight: FontWeight.w700);
@override
Widget build(BuildContext context) {
Get.put(ButtonController());
/// just to have a mouse over / out state.
return MouseRegion(
/// cursor: SystemMouseCursors.click, // only on dev channel
onEnter: (e) => controller.isOver(true),
onExit: (e) => controller.isOver(false),
child: GestureDetector(
onTap: controller.toggleAnimation,
child: Obx(
() {
controller.isLoading();
return AnimatedContainer(
duration: .5.seconds,
curve: Curves.easeOutExpo,
width: controller.w,
height: controller.h,
decoration: BoxDecoration(
color: controller.backgroundColor,
borderRadius: BorderRadius.circular(controller.radius),
),
alignment: Alignment.center,
child: AnimatedCrossFade(
alignment: Alignment.center,
duration: .15.seconds,
reverseDuration: .25.seconds,
crossFadeState: controller.fadeState,
firstCurve: Curves.easeIn,
secondCurve: Curves.easeIn,
firstChild: Text('Conectar', style: labelStyle, maxLines: 1),
secondChild: SizedBox(
width: 18,
height: 18,
child: CircularProgressIndicator(
strokeWidth: 2.5,
valueColor: AlwaysStoppedAnimation(Colors.white),
),
),
/// to keep the widgets centered.
layoutBuilder:
(Widget top, Key topKey, Widget bottom, Key bottomKey) =>
Stack(children: [
Positioned.fill(key: bottomKey, child: Center(child: bottom)),
Positioned.fill(key: topKey, child: Center(child: top))
]),
),
);
},
),
),
);
}
}
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: Text(
'Submit button loading animation.',
style: TextStyle(color: Colors.white30),
),
backgroundColor: Colors.grey.withOpacity(.12),
),
backgroundColor: Colors.black,
body: Center(child: ButtonLoader()),
),
),
);
}
/// GetX v3.24.0 minified version for dartpad and codepen.io
/// roipeker 2021.
///
/// NOTES:
/// - place imports at the top of your gists.
/// - place the rest of the code at the end of it.
///
html.Navigator _navigator = html.window.navigator;bool isTokenChar(int byte) => byte > 31 && byte < 128 && !SEPARATOR_MAP[byte];bool isValueChar(int byte) => (byte > 31 && byte < 128) || (byte == CharCode.SP) || (byte == CharCode.HT);class CharCode {static const int HT = 9, LF = 10, CR = 13, SP = 32, COMMA = 44, SLASH = 47, ZERO = 48, ONE = 49, COLON = 58, SEMI_COLON = 59;}const bool F = false;const bool T = true;const SEPARATOR_MAP = [F, F, F, F, F, F, F, F, F, T, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, T, F, T, F, F, F, F, F, T, T, F, F, T, F, F, T, F, F, F, F, F, F, F, F, F, F, T, T, T, T, T, T, T, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, T, T, T, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, T, F, T, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F];String validateField(String field) {for (var i = 0; i < field.length; i++) if (!isTokenChar(field.codeUnitAt(i))) throw FormatException('Invalid HTTP header field name: ${json.encode(field)}', field, i);return field.toLowerCase();}BodyBytesStream toBodyBytesStream(Stream<List<int>> stream) {if (stream is BodyBytesStream) return stream;return BodyBytesStream(stream);}final _asciiOnly = RegExp(r'^[\x00-\x7F]+$');final newlineRegExp = RegExp(r'\r\n|\r|\n');bool isPlainAscii(String string) => _asciiOnly.hasMatch(string);const String GET_BOUNDARY = 'getx-http-boundary-';String browserEncode(String value) => value.replaceAll(newlineRegExp, '%0D%0A').replaceAll('"', '%22');const List<int> boundaryCharacters = <int>[43, 95, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122];Future<String> bodyBytesToString(BodyBytesStream bodyBytes, Map<String, String> headers) => bodyBytes.bytesToString(_encodingForHeaders(headers));Encoding _encodingForHeaders(Map<String, String> headers) => _encodingForCharset(_contentTypeForHeaders(headers).parameters['charset']);Encoding _encodingForCharset(String charset, [Encoding fallback = latin1]) => (charset == null) ? fallback : Encoding.getByName(charset) ?? fallback;HeaderValue _contentTypeForHeaders(Map<String, String> headers) {var contentType = headers['content-type'];if (contentType != null) return HeaderValue.parse(contentType);return HeaderValue('application/octet-stream');}final Get = _GetImpl();T bodyDecoded<T>(Request<T> request, String stringBody, String mimeType) {T body;var bodyToDecode;if (mimeType != null && mimeType.contains('application/json')) {try {bodyToDecode = jsonDecode(stringBody);} on FormatException catch (_) {Get.log('Cannot decode server response to json');bodyToDecode = stringBody;}} else {bodyToDecode = stringBody;}try {if (stringBody == '') {body = null;} else if (request.decoder == null) {body = bodyToDecode as T;} else {body = request.decoder(bodyToDecode);}} on Exception catch (_) {body = stringBody as T;}return body;}List<int> fileToBytes(dynamic data) => (data is List<int>) ? data : throw FormatException('File is not [File] or [String] or [List<int>]');String _extractRouteName(Route route) {if (route?.settings?.name != null) return route.settings.name;if (route is GetPageRoute) return route.routeName;if (route is GetDialogRoute) return route.name;if (route is GetModalBottomSheetRoute) return route.name;return null;}NavigatorState get navigator => GetNavigation(Get).key.currentState;bool _isEmpty(dynamic value) {if (value is String) return value.toString().trim().isEmpty;if (value is Iterable || value is Map) return value.isEmpty as bool;return false;}bool _hasLength(dynamic value) => value is Iterable || value is String || value is Map;int _obtainDynamicLength(dynamic value) {if (value == null) return null;if (_hasLength(value)) return value.length as int;if (value is int) return value.toString().length;if (value is double) return value.toString().replaceAll('.', '').length;return null;}bool _conditional(dynamic condition) {if (condition == null) return true;if (condition is bool) return condition;if (condition is bool Function()) return condition();return true;}
void defaultLogWriterCallback(String value, {bool isError = false}) {if (isError || Get.isLogEnable) developer.log(value, name: 'GETX');}Worker ever<T>(RxInterface<T> listener, WorkerCallback<T> callback, {dynamic condition = true, Function onError, void Function() onDone, bool cancelOnError}) {StreamSubscription sub = listener.listen((event) {if (_conditional(condition)) callback(event);}, onError: onError, onDone: onDone, cancelOnError: cancelOnError);return Worker(sub.cancel, '[ever]');}Worker everAll(List<RxInterface> listeners, WorkerCallback callback, {dynamic condition = true, Function onError, void Function() onDone, bool cancelOnError}) {final evers = <StreamSubscription>[];for (var i in listeners) {final sub = i.listen((event) { if (_conditional(condition)) callback(event); }, onError: onError, onDone: onDone, cancelOnError: cancelOnError); evers.add(sub);}Future<void> cancel() {for (var i in evers) i.cancel(); return Future.value(() {});}return Worker(cancel, '[everAll]');}Worker once<T>(RxInterface<T> listener, WorkerCallback<T> callback, {dynamic condition = true, Function onError, void Function() onDone, bool cancelOnError}) {Worker ref;StreamSubscription sub;sub = listener.listen((event) {if (!_conditional(condition)) return;ref._disposed = true;ref._log('called');sub?.cancel();callback(event);}, onError: onError, onDone: onDone, cancelOnError: cancelOnError);ref = Worker(sub.cancel, '[once]');return ref;}Worker interval<T>(RxInterface<T> listener, WorkerCallback<T> callback, {Duration time = const Duration(seconds: 1), dynamic condition = true, Function onError, void Function() onDone, bool cancelOnError}) {var debounceActive = false;time ??= const Duration(seconds: 1);StreamSubscription sub = listener.listen((event) async {if (debounceActive || !_conditional(condition)) return;debounceActive = true;await Future.delayed(time);debounceActive = false;callback(event);}, onError: onError, onDone: onDone, cancelOnError: cancelOnError);return Worker(sub.cancel, '[interval]');}Worker debounce<T>(RxInterface<T> listener, WorkerCallback<T> callback, {Duration time, Function onError, void Function() onDone, bool cancelOnError}) {final _debouncer = Debouncer(delay: time ?? const Duration(milliseconds: 800));StreamSubscription sub = listener.listen((event) => _debouncer(() => callback(event)), onError: onError, onDone: onDone, cancelOnError: cancelOnError);return Worker(sub.cancel, '[debounce]');}
const double _kBackGestureWidth = 20.0;const double _kMinFlingVelocity = 1.0;const int _kMaxDroppedSwipePageForwardAnimationTime = 800;const int _kMaxPageBackAnimationTime = 300;const List<String> rtlLanguages = <String>['ar', 'fa', 'he', 'ps', 'ur'];
typedef Decoder<T> = T Function(dynamic data);typedef Progress = Function(double percent);typedef RequestModifier<T> = FutureOr<Request<T>> Function(Request<T> request);typedef ResponseModifier<T> = FutureOr Function(Request<T> request, Response<T> response);typedef HandlerExecute<T> = Future<Request<T>> Function();typedef MockClientHandler = Future<Response> Function(Request request);typedef OpenSocket = void Function();typedef CloseSocket = void Function(Close);typedef MessageSocket = void Function(dynamic val);typedef LogWriterCallback = void Function(String text, {bool isError});typedef ValueUpdater<T> = T Function();typedef BindingBuilderCallback = void Function();typedef InstanceBuilderCallback<S> = S Function();typedef InjectorBuilderCallback<S> = S Function(GetInstance);typedef AsyncInstanceBuilderCallback<S> = Future<S> Function();typedef GetPageBuilder = Widget Function();typedef SnackbarStatusCallback = void Function(SnackbarStatus status);typedef OnTap = void Function(GetBar snack);typedef RemoveSubscription<T> = FutureOr<bool> Function(LightSubscription<T> subs);typedef AddSubscription<T> = FutureOr<void> Function(LightSubscription<T> subs);typedef Condition = bool Function();typedef OnData<T> = void Function(T data);typedef Callback = void Function();typedef WorkerCallback<T> = Function(T callback);typedef GetXControllerBuilder<T extends DisposableInterface> = Widget Function(T controller);typedef NotifierBuilder<T> = Widget Function(T state);typedef WidgetCallback = Widget Function();typedef GetControllerBuilder<T extends DisposableInterface> = Widget Function(T controller);typedef Disposer = void Function();typedef GetStateUpdate = void Function();typedef ValueBuilderBuilder<T> = Widget Function(T snapshot, ValueBuilderUpdateCallback<T> updater);typedef ValueBuilderUpdateCallback<T> = void Function(T snapshot);typedef PrintFunctionCallback = void Function(String prefix, dynamic value, String info, {bool isError});
enum SmartManagement { full, onlyBuilder, keepFactory }enum ConnectionStatus { connecting, connected, closed }enum Transition { fade, fadeIn, rightToLeft, leftToRight, upToDown, downToUp, rightToLeftWithFade, leftToRightWithFade, zoom, topLevel, noTransition, cupertino, cupertinoDialog, size, native }enum SnackPosition { TOP, BOTTOM }enum SnackStyle { FLOATING, GROUNDED }enum SnackDismissDirection { HORIZONTAL, VERTICAL }enum SnackbarStatus { OPEN, CLOSED, OPENING, CLOSING }enum ScreenType { Watch, Phone, Tablet, Desktop }
abstract class Translations {Map<String, Map<String, String>> get keys;}abstract class CustomTransition {Widget buildTransition(BuildContext context, Curve curve, Alignment alignment, Animation<double> animation, Animation<double> secondaryAnimation, Widget child);}abstract class GetConnectInterface with GetLifeCycleBase {List<GetSocket> sockets;GetHttpClient get httpClient;Future<Response<T>> get<T>(String url, {Map<String, String> headers, String contentType, Map<String, dynamic> query, Decoder<T> decoder});Future<Response<T>> request<T>(String url, String method, {dynamic body, String contentType, Map<String, String> headers, Map<String, dynamic> query, Decoder<T> decoder});Future<Response<T>> post<T>(String url, dynamic body, {String contentType, Map<String, String> headers, Map<String, dynamic> query, Decoder<T> decoder});Future<Response<T>> put<T>(String url, dynamic body, {String contentType, Map<String, String> headers, Map<String, dynamic> query, Decoder<T> decoder});Future<Response<T>> delete<T>(String url, {Map<String, String> headers, String contentType, Map<String, dynamic> query, Decoder<T> decoder});Future<Response<T>> patch<T>(String url, dynamic body, {String contentType, Map<String, String> headers, Map<String, dynamic> query, Decoder<T> decoder, Progress uploadProgress});Future<GraphQLResponse<T>> query<T>(String query, {String url, Map<String, dynamic> variables, Map<String, String> headers});Future<GraphQLResponse<T>> mutation<T>(String mutation, {String url, Map<String, dynamic> variables, Map<String, String> headers});GetSocket socket(String url, {Duration ping = const Duration(seconds: 5)});}abstract class HttpRequestBase {Future<Response<T>> send<T>(Request<T> request);void close();}abstract class GetInterface {SmartManagement smartManagement = SmartManagement.full;String reference;bool isLogEnable = true;LogWriterCallback log = defaultLogWriterCallback;}abstract class Bindings {void dependencies();}abstract class GetLifeCycle with GetLifeCycleBase {GetLifeCycle() {$configureLifeCycle();}}abstract class GetView<T> extends StatelessWidget {const GetView({Key key}) : super(key: key);final String tag = null;T get controller => GetInstance().find<T>(tag: tag);@override Widget build(BuildContext context);}abstract class GetWidget<S extends GetLifeCycleBase> extends GetWidgetCache {const GetWidget({Key key}) : super(key: key);@protected final String tag = null;S get controller => GetWidget._cache[this] as S;static final _cache = Expando<GetLifeCycleBase>();@protected Widget build(BuildContext context);@override WidgetCache createWidgetCache() => _GetCache<S>();}abstract class ObxWidget extends StatefulWidget {const ObxWidget({Key key}) : super(key: key);@override _ObxState createState() => _ObxState();@protected Widget build();}abstract class GetxService extends DisposableInterface with GetxServiceMixin {}abstract class DisposableInterface extends GetLifeCycle {@override @mustCallSuper void onInit() {super.onInit();SchedulerBinding.instance?.addPostFrameCallback((_) => onReady());}@override void onReady() => super.onReady();@override void onClose() => super.onClose();}abstract class RxInterface<T> {RxInterface([T initial]);bool get canUpdate;void addListener(GetStream<T> rxGetx);void close();static RxInterface proxy;StreamSubscription<T> listen(void Function(T event) onData, {Function onError, void Function() onDone, bool cancelOnError});}abstract class _BaseRxNum<T extends num> extends _RxImpl<T> {_BaseRxNum(T initial) : super(initial);num operator *(num other) => value * other;num operator %(num other) => value % other;double operator /(num other) => value / other;int operator ~/(num other) => value ~/ other;num operator -() => -value;num remainder(num other) => value.remainder(other);bool operator <(num other) => value < other;bool operator <=(num other) => value <= other;bool operator >(num other) => value > other;bool operator >=(num other) => value >= other;bool get isNaN => value.isNaN;bool get isNegative => value.isNegative;bool get isInfinite => value.isInfinite;bool get isFinite => value.isFinite;num abs() => value.abs();num get sign => value.sign;int round() => value.round();int floor() => value.floor();int ceil() => value.ceil();int truncate() => value.truncate();double roundToDouble() => value.roundToDouble();double floorToDouble() => value.floorToDouble();double ceilToDouble() => value.ceilToDouble();double truncateToDouble() => value.truncateToDouble();num clamp(num lowerLimit, num upperLimit) => value.clamp(lowerLimit, upperLimit);int toInt() => value.toInt();double toDouble() => value.toDouble();String toStringAsFixed(int fractionDigits) => value.toStringAsFixed(fractionDigits);String toStringAsExponential([int fractionDigits]) => value.toStringAsExponential(fractionDigits);String toStringAsPrecision(int precision) => value.toStringAsPrecision(precision);}abstract class GetNotifier<T> extends Value<T> with GetLifeCycleBase {GetNotifier(T initial) : super(initial) {$configureLifeCycle();} @override @mustCallSuper void onInit() {super.onInit();SchedulerBinding.instance?.addPostFrameCallback((_) => onReady());}}abstract class GetxController extends DisposableInterface with ListNotifier {void update([List<Object> ids, bool condition = true]) {if (!condition) return;if (ids == null) {refresh();} else {for (final id in ids) {refreshGroup(id);}}}}abstract class RxController extends DisposableInterface {}abstract class SuperController<T> extends FullLifeCycleController with FullLifeCycle, StateMixin<T> {}abstract class FullLifeCycleController extends GetxController with WidgetsBindingObserver {}abstract class _GetResponsive<T> extends GetView<T> {final ResponsiveScreen screen;_GetResponsive(ResponsiveScreenSettings settings, {Key key}): screen = ResponsiveScreen(settings), super(key: key);Widget builder();Widget phone();Widget tablet();Widget desktop();Widget watch();}abstract class GetWidgetCache extends Widget {const GetWidgetCache({Key key}) : super(key: key);@override GetWidgetCacheElement createElement() => GetWidgetCacheElement(this);@protected @factory WidgetCache createWidgetCache();}abstract class _RxImpl<T> extends RxNotifier<T> with RxObjectMixin<T> {_RxImpl(T initial) {_value = initial;}void addError(Object error, [StackTrace stackTrace]) => subject.addError(error, stackTrace);Stream<R> map<R>(R mapper(T data)) => stream.map(mapper);void update(void fn(T val)) {fn(_value);subject.add(_value);}}abstract class _RouteMiddleware {int priority;RouteSettings redirect(String route);GetPage onPageCalled(GetPage page);List<Bindings> onBindingsStart(List<Bindings> bindings);GetPageBuilder onPageBuildStart(GetPageBuilder page);Widget onPageBuilt(Widget page);void onPageDispose();}@optionalTypeArgs abstract class WidgetCache<T extends GetWidgetCache> {T get widget => _widget; T _widget;BuildContext get context => _element;GetWidgetCacheElement _element;@protected @mustCallSuper void onInit() {}@protected @mustCallSuper void onClose() {}@protected Widget build(BuildContext context);}
mixin RxObjectMixin<T> on NotifyManager<T> {T _value;void refresh() => subject.add(value);void nil() => subject.add(_value = null);T call([T v]) {if (v != null) value = v;return value;}bool firstRebuild = true;String get string => value.toString();@override String toString() => value.toString();dynamic toJson() => value;@override bool operator ==(dynamic o) {if (o is T) return value == o;if (o is RxObjectMixin<T>) return value == o.value;return false;}@override int get hashCode => _value.hashCode;set value(T val) {if (_value == val && !firstRebuild) return;firstRebuild = false;_value = val;subject.add(_value);}T get value {if (RxInterface.proxy != null) RxInterface.proxy.addListener(subject);return _value;}Stream<T> get stream => subject.stream;void bindStream(Stream<T> stream) => _subscriptions.add(stream.listen((va) => value = va));}mixin NotifyManager<T> {GetStream<T> subject = GetStream<T>();final _subscriptions = <StreamSubscription>[];bool get canUpdate => _subscriptions.isNotEmpty;void addListener(GetStream<T> rxGetx) {if (_subscriptions.contains(rxGetx.listen)) return;final subs = rxGetx.listen((data) => subject.add(data));_subscriptions.add(subs);}StreamSubscription<T> listen(void Function(T) onData, {Function onError, void Function() onDone, bool cancelOnError = false}) => subject.listen(onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError);void close() {for (final subscription in _subscriptions) subscription?.cancel();_subscriptions.clear();subject.close();}}mixin GetLifeCycleBase {final onStart = _InternalFinalCallback<void>();final onDelete = _InternalFinalCallback<void>();bool _initialized = false;bool _isClosed = false;void onInit() {}void onReady() {}void onClose() {}bool get initialized => _initialized;void _onStart() {if (_initialized) return;onInit();_initialized = true;}bool get isClosed => _isClosed;void _onDelete() {if (_isClosed) return;_isClosed = true;onClose();}void $configureLifeCycle() {_checkIfAlreadyConfigured();onStart._callback = _onStart;onDelete._callback = _onDelete;}void _checkIfAlreadyConfigured() {if (_initialized) {throw """You can only call configureLifeCycle once. \nThe proper place to insert it is in your class's constructor\nthat inherits GetLifeCycle.""";}}}mixin GetxServiceMixin {}mixin StateMixin<T> on ListNotifier {T _value; RxStatus _status;bool _isNullOrEmpty(dynamic val) {if (val == null) return true;if (val is Iterable) return val.isEmpty;if (val is String) return val.isEmpty;if (val is Map) return val.isEmpty;return false;}void _fillEmptyStatus() => _status = _isNullOrEmpty(_value) ? RxStatus.loading() : RxStatus.success();RxStatus get status {notifyChildrens();return _status ??= _status = RxStatus.loading();}T get state => value;@protected T get value {notifyChildrens();return _value;}@protected set value(T newValue) {if (_value == newValue) return;_value = newValue;refresh();}@protected void change(T newState, {RxStatus status}) {var _canUpdate = false;if (status != null) {_status = status;_canUpdate = true;}if (newState != _value) {_value = newState;_canUpdate = true;}if (_canUpdate) refresh();}}mixin SingleGetTickerProviderMixin on DisposableInterface implements TickerProvider {@override Ticker createTicker(TickerCallback onTick) => Ticker(onTick);}mixin FullLifeCycle on FullLifeCycleController {@mustCallSuper @override void onInit() {super.onInit();WidgetsBinding.instance.addObserver(this);}@mustCallSuper @override void onClose() {WidgetsBinding.instance.removeObserver(this);super.onClose();}@mustCallSuper @override void didChangeAppLifecycleState(AppLifecycleState state) {switch (state) {case AppLifecycleState.resumed:onResumed();break;case AppLifecycleState.inactive:onInactive();break;case AppLifecycleState.paused:onPaused();break;case AppLifecycleState.detached:onDetached();break;}}void onResumed();void onPaused();void onInactive();void onDetached();}mixin GetStateUpdaterMixin<T extends StatefulWidget> on State<T> {void getUpdate() {if (mounted) setState(() {});}}
extension ExtensionSnackbar on GetInterface {void rawSnackbar({String title, String message, Widget titleText, Widget messageText, Widget icon, bool instantInit = true, bool shouldIconPulse = true, double maxWidth, EdgeInsets margin = const EdgeInsets.all(0.0), EdgeInsets padding = const EdgeInsets.all(16), double borderRadius = 0.0, Color borderColor, double borderWidth = 1.0, Color backgroundColor = const Color(0xFF303030), Color leftBarIndicatorColor, List<BoxShadow> boxShadows, Gradient backgroundGradient, FlatButton mainButton, OnTap onTap, Duration duration = const Duration(seconds: 3), bool isDismissible = true, SnackDismissDirection dismissDirection = SnackDismissDirection.VERTICAL, bool showProgressIndicator = false, AnimationController progressIndicatorController, Color progressIndicatorBackgroundColor, Animation<Color> progressIndicatorValueColor, SnackPosition snackPosition = SnackPosition.BOTTOM, SnackStyle snackStyle = SnackStyle.FLOATING, Curve forwardAnimationCurve = Curves.easeOutCirc, Curve reverseAnimationCurve = Curves.easeOutCirc, Duration animationDuration = const Duration(seconds: 1), SnackbarStatusCallback snackbarStatus, double barBlur = 0.0, double overlayBlur = 0.0, Color overlayColor, Form userInputForm}) async {final getBar = GetBar(snackbarStatus: snackbarStatus, title: title, message: message, titleText: titleText, messageText: messageText, snackPosition: snackPosition, borderRadius: borderRadius, margin: margin, duration: duration, barBlur: barBlur, backgroundColor: backgroundColor, icon: icon, shouldIconPulse: shouldIconPulse, maxWidth: maxWidth, padding: padding, borderColor: borderColor, borderWidth: borderWidth, leftBarIndicatorColor: leftBarIndicatorColor, boxShadows: boxShadows, backgroundGradient: backgroundGradient, mainButton: mainButton, onTap: onTap, isDismissible: isDismissible, dismissDirection: dismissDirection, showProgressIndicator: showProgressIndicator ?? false, progressIndicatorController: progressIndicatorController, progressIndicatorBackgroundColor: progressIndicatorBackgroundColor, progressIndicatorValueColor: progressIndicatorValueColor, snackStyle: snackStyle, forwardAnimationCurve: forwardAnimationCurve, reverseAnimationCurve: reverseAnimationCurve, animationDuration: animationDuration, overlayBlur: overlayBlur, overlayColor: overlayColor, userInputForm: userInputForm);if (instantInit) {getBar.show();} else {SchedulerBinding.instance.addPostFrameCallback((_) => getBar.show());}}Future<T> showSnackbar<T>(GetBar snackbar) => key?.currentState?.push(SnackRoute<T>(snack: snackbar));void snackbar<T>(String title, String message, {Color colorText, Duration duration, bool instantInit = true, SnackPosition snackPosition, Widget titleText, Widget messageText, Widget icon, bool shouldIconPulse, double maxWidth, EdgeInsets margin, EdgeInsets padding, double borderRadius, Color borderColor, double borderWidth, Color backgroundColor, Color leftBarIndicatorColor, List<BoxShadow> boxShadows, Gradient backgroundGradient, FlatButton mainButton, OnTap onTap, bool isDismissible, bool showProgressIndicator, SnackDismissDirection dismissDirection, AnimationController progressIndicatorController, Color progressIndicatorBackgroundColor, Animation<Color> progressIndicatorValueColor, SnackStyle snackStyle, Curve forwardAnimationCurve, Curve reverseAnimationCurve, Duration animationDuration, double barBlur, double overlayBlur, SnackbarStatusCallback snackbarStatus, Color overlayColor, Form userInputForm}) async {final getBar = GetBar(titleText: (title == null) ? null : titleText ?? Text(title, style: TextStyle(color: colorText ?? iconColor ?? Colors.black, fontWeight: FontWeight.w800, fontSize: 16)), messageText: messageText ?? Text(message, style: TextStyle(color: colorText ?? iconColor ?? Colors.black, fontWeight: FontWeight.w300, fontSize: 14)), snackPosition: snackPosition ?? SnackPosition.TOP, borderRadius: borderRadius ?? 15, margin: margin ?? EdgeInsets.symmetric(horizontal: 10), duration: duration ?? Duration(seconds: 3), barBlur: barBlur ?? 7.0, backgroundColor: backgroundColor ?? Colors.grey.withOpacity(0.2), icon: icon, shouldIconPulse: shouldIconPulse ?? true, maxWidth: maxWidth, padding: padding ?? EdgeInsets.all(16), borderColor: borderColor, borderWidth: borderWidth, leftBarIndicatorColor: leftBarIndicatorColor, boxShadows: boxShadows, backgroundGradient: backgroundGradient, mainButton: mainButton, onTap: onTap, isDismissible: isDismissible ?? true, dismissDirection: dismissDirection ?? SnackDismissDirection.VERTICAL, showProgressIndicator: showProgressIndicator ?? false, progressIndicatorController: progressIndicatorController, progressIndicatorBackgroundColor: progressIndicatorBackgroundColor, progressIndicatorValueColor: progressIndicatorValueColor, snackStyle: snackStyle ?? SnackStyle.FLOATING, forwardAnimationCurve: forwardAnimationCurve ?? Curves.easeOutCirc, reverseAnimationCurve: reverseAnimationCurve ?? Curves.easeOutCirc, animationDuration: animationDuration ?? Duration(seconds: 1), overlayBlur: overlayBlur ?? 0.0, overlayColor: overlayColor ?? Colors.transparent, snackbarStatus: snackbarStatus, userInputForm: userInputForm);if (instantInit) {showSnackbar<T>(getBar);} else {routing.isSnackbar = true;SchedulerBinding.instance.addPostFrameCallback((_) => showSnackbar<T>(getBar));}}}extension ExtensionDialog on GetInterface {Future<T> dialog<T>(Widget widget, {bool barrierDismissible = true, Color barrierColor, bool useSafeArea = true, bool useRootNavigator = true, Object arguments, Duration transitionDuration, Curve transitionCurve, String name, RouteSettings routeSettings}) {assert(widget != null);assert(barrierDismissible != null);assert(useSafeArea != null);assert(useRootNavigator != null);assert(debugCheckHasMaterialLocalizations(context));final theme = Theme.of(context);return generalDialog<T>(pageBuilder: (buildContext, animation, secondaryAnimation) {final pageChild = widget;Widget dialog = Builder(builder: (context) => theme != null ? Theme(data: theme, child: pageChild) : pageChild);if (useSafeArea) dialog = SafeArea(child: dialog);return dialog;}, barrierDismissible: barrierDismissible, barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel, barrierColor: barrierColor ?? Colors.black54, transitionDuration: transitionDuration ?? defaultDialogTransitionDuration, transitionBuilder: (context, animation, secondaryAnimation, child) => FadeTransition(opacity: CurvedAnimation(parent: animation, curve: transitionCurve ?? defaultDialogTransitionCurve), child: child), useRootNavigator: useRootNavigator, routeSettings: routeSettings ?? RouteSettings(arguments: arguments, name: name));}Future<T> generalDialog<T>({@required RoutePageBuilder pageBuilder, bool barrierDismissible = false, String barrierLabel, Color barrierColor = const Color(0x80000000), Duration transitionDuration = const Duration(milliseconds: 200), RouteTransitionsBuilder transitionBuilder, bool useRootNavigator = true, RouteSettings routeSettings}) {assert(pageBuilder != null);assert(useRootNavigator != null);assert(!barrierDismissible || barrierLabel != null);return Navigator.of(overlayContext, rootNavigator: useRootNavigator).push<T>(GetDialogRoute<T>(pageBuilder: pageBuilder, barrierDismissible: barrierDismissible, barrierLabel: barrierLabel, barrierColor: barrierColor, transitionDuration: transitionDuration, transitionBuilder: transitionBuilder, settings: routeSettings));}Future<T> defaultDialog<T>({String title = "Alert", TextStyle titleStyle, Widget content, VoidCallback onConfirm, VoidCallback onCancel, VoidCallback onCustom, Color cancelTextColor, Color confirmTextColor, String textConfirm, String textCancel, String textCustom, Widget confirm, Widget cancel, Widget custom, Color backgroundColor, bool barrierDismissible = true, Color buttonColor, String middleText = "Dialog made in 3 lines of code", TextStyle middleTextStyle, double radius = 20.0, List<Widget> actions, WillPopCallback onWillPop}) {var leanCancel = onCancel != null || textCancel != null;var leanConfirm = onConfirm != null || textConfirm != null;actions ??= [];if (cancel != null) {actions.add(cancel);} else {if (leanCancel) actions.add(FlatButton(materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, onPressed: () {onCancel?.call();back();}, padding: EdgeInsets.symmetric(horizontal: 10, vertical: 8), child: Text(textCancel ?? "Cancel", style: TextStyle(color: cancelTextColor ?? theme.accentColor)), shape: RoundedRectangleBorder(side: BorderSide(color: buttonColor ?? theme.accentColor, width: 2, style: BorderStyle.solid), borderRadius: BorderRadius.circular(100))));}if (confirm != null) {actions.add(confirm);} else {if (leanConfirm) {actions.add(FlatButton(materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, color: buttonColor ?? theme.accentColor, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(100)), child: Text(textConfirm ?? "Ok", style: TextStyle(color: confirmTextColor ?? theme.primaryColor)), onPressed: () => onConfirm?.call()));}}Widget baseAlertDialog = AlertDialog(titlePadding: EdgeInsets.all(8), contentPadding: EdgeInsets.all(8), backgroundColor: backgroundColor ?? theme.dialogBackgroundColor, shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(radius))), title: Text(title, textAlign: TextAlign.center, style: titleStyle), content: Column(crossAxisAlignment: CrossAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [content ?? Text(middleText ?? "", textAlign: TextAlign.center, style: middleTextStyle), SizedBox(height: 16), ButtonTheme(minWidth: 78.0, height: 34.0, child: Wrap(alignment: WrapAlignment.center, spacing: 8, runSpacing: 8, children: actions))],), buttonPadding: EdgeInsets.zero,);if (onWillPop != null) return dialog<T>(WillPopScope(onWillPop: onWillPop, child: baseAlertDialog), barrierDismissible: barrierDismissible);return dialog<T>(baseAlertDialog, barrierDismissible: barrierDismissible);}}extension ExtensionBottomSheet on GetInterface {Future<T> bottomSheet<T>(Widget bottomsheet, {Color backgroundColor, double elevation, bool persistent = true, ShapeBorder shape, Clip clipBehavior, Color barrierColor, bool ignoreSafeArea, bool isScrollControlled = false, bool useRootNavigator = false, bool isDismissible = true, bool enableDrag = true, RouteSettings settings, Duration enterBottomSheetDuration, Duration exitBottomSheetDuration}) {assert(bottomsheet != null);assert(persistent != null);assert(isScrollControlled != null);assert(useRootNavigator != null);assert(isDismissible != null);assert(enableDrag != null);return Navigator.of(overlayContext, rootNavigator: useRootNavigator).push(GetModalBottomSheetRoute<T>(builder: (_) => bottomsheet, isPersistent: persistent, theme: Theme.of(key.currentContext), isScrollControlled: isScrollControlled, barrierLabel: MaterialLocalizations.of(key.currentContext).modalBarrierDismissLabel, backgroundColor: backgroundColor ?? Colors.transparent, elevation: elevation, shape: shape, removeTop: ignoreSafeArea ?? true, clipBehavior: clipBehavior, isDismissible: isDismissible, modalBarrierColor: barrierColor, settings: settings, enableDrag: enableDrag));}}extension GetNavigation on GetInterface {Future<T> to<T>(Widget page, {bool opaque, Transition transition, Curve curve, Duration duration, int id, bool fullscreenDialog = false, dynamic arguments, Bindings binding, bool preventDuplicates = true, bool popGesture}) {var routeName = "/${page.runtimeType.toString()}";if (preventDuplicates && routeName == currentRoute) return null;return global(id)?.currentState?.push<T>(GetPageRoute<T>(opaque: opaque ?? true, page: () => page, routeName: routeName, settings: RouteSettings(arguments: arguments), popGesture: popGesture ?? defaultPopGesture, transition: transition ?? defaultTransition, curve: curve ?? defaultTransitionCurve, fullscreenDialog: fullscreenDialog, binding: binding, transitionDuration: duration ?? defaultTransitionDuration));}Future<T> toNamed<T>(String page, {dynamic arguments, int id, bool preventDuplicates = true}) {if (preventDuplicates && page == currentRoute) return null;return global(id)?.currentState?.pushNamed<T>(page, arguments: arguments);}Future<T> offNamed<T>(String page, {dynamic arguments, int id, bool preventDuplicates = true}) {if (preventDuplicates && page == currentRoute) return null;return global(id)?.currentState?.pushReplacementNamed(page, arguments: arguments);}void until(RoutePredicate predicate, {int id}) => global(id)?.currentState?.popUntil(predicate);Future<T> offUntil<T>(Route<T> page, RoutePredicate predicate, {int id}) => global(id)?.currentState?.pushAndRemoveUntil<T>(page, predicate);Future<T> offNamedUntil<T>(String page, RoutePredicate predicate, {int id, dynamic arguments}) => global(id)?.currentState?.pushNamedAndRemoveUntil<T>(page, predicate, arguments: arguments);Future<T> offAndToNamed<T>(String page, {dynamic arguments, int id, dynamic result}) => global(id)?.currentState?.popAndPushNamed(page, arguments: arguments, result: result);void removeRoute(Route<dynamic> route, {int id}) => global(id)?.currentState?.removeRoute(route);Future<T> offAllNamed<T>(String newRouteName, {RoutePredicate predicate, dynamic arguments, int id}) => global(id)?.currentState?.pushNamedAndRemoveUntil<T>(newRouteName, predicate ?? (_) => false, arguments: arguments);bool get isOverlaysOpen => (isSnackbarOpen || isDialogOpen || isBottomSheetOpen);bool get isOverlaysClosed => (!isSnackbarOpen && !isDialogOpen && !isBottomSheetOpen);void back<T>({T result, bool closeOverlays = false, bool canPop = true, int id}) {if (closeOverlays && isOverlaysOpen) {navigator?.popUntil((route) => (isOverlaysClosed));}if (canPop) {if (global(id)?.currentState?.canPop() == true) global(id)?.currentState?.pop<T>(result);} else {global(id)?.currentState?.pop<T>(result);}}void close(int times, [int id]) {if ((times == null) || (times < 1)) times = 1;var count = 0;var back = global(id)?.currentState?.popUntil((route) => count++ == times);return back;}Future<T> off<T>(Widget page, {bool opaque = false, Transition transition, Curve curve, bool popGesture, int id, dynamic arguments, Bindings binding, bool fullscreenDialog = false, bool preventDuplicates = true, Duration duration}) {var routeName = "/${page.runtimeType.toString()}";if (preventDuplicates && routeName == currentRoute) return null;return global(id)?.currentState?.pushReplacement(GetPageRoute(opaque: opaque ?? true, page: () => page, binding: binding, settings: RouteSettings(arguments: arguments), routeName: routeName, fullscreenDialog: fullscreenDialog, popGesture: popGesture ?? defaultPopGesture, transition: transition ?? defaultTransition, curve: curve ?? defaultTransitionCurve, transitionDuration: duration ?? defaultTransitionDuration));}Future<T> offAll<T>(Widget page, {RoutePredicate predicate, bool opaque = false, bool popGesture, int id, dynamic arguments, Bindings binding, bool fullscreenDialog = false, Transition transition, Curve curve, Duration duration}) {var routeName = "/${page.runtimeType.toString()}";return global(id)?.currentState?.pushAndRemoveUntil<T>(GetPageRoute<T>(opaque: opaque ?? true, popGesture: popGesture ?? defaultPopGesture, page: () => page, binding: binding, settings: RouteSettings(arguments: arguments), fullscreenDialog: fullscreenDialog, routeName: routeName, transition: transition ?? defaultTransition, curve: curve ?? defaultTransitionCurve, transitionDuration: duration ?? defaultTransitionDuration), predicate ?? (route) => false);}void addPages(List<GetPage> getPages) {if (getPages != null) {if (routeTree == null) routeTree = ParseRouteTree();routeTree.addRoutes(getPages);}}void addPage(GetPage getPage) {if (getPage != null) {if (routeTree == null) routeTree = ParseRouteTree();routeTree.addRoute(getPage);}}void config({bool enableLog, LogWriterCallback logWriterCallback, bool defaultPopGesture, bool defaultOpaqueRoute, Duration defaultDurationTransition, bool defaultGlobalState, Transition defaultTransition}) {if (enableLog != null) Get.isLogEnable = enableLog;if (logWriterCallback != null) Get.log = logWriterCallback;if (defaultPopGesture != null) getxController.defaultPopGesture = defaultPopGesture;if (defaultOpaqueRoute != null) getxController.defaultOpaqueRoute = defaultOpaqueRoute;if (defaultTransition != null) getxController.defaultTransition = defaultTransition;if (defaultDurationTransition != null) getxController.defaultTransitionDuration = defaultDurationTransition;}void updateLocale(Locale l) {Get.locale = l;forceAppUpdate();}void forceAppUpdate() => engine.performReassemble();void appUpdate() => getxController.update();void changeTheme(ThemeData theme) => getxController.setTheme(theme);void changeThemeMode(ThemeMode themeMode) => getxController.setThemeMode(themeMode);GlobalKey<NavigatorState> addKey(GlobalKey<NavigatorState> newKey) {getxController.key = newKey;return key;}GlobalKey<NavigatorState> nestedKey(int key) {keys.putIfAbsent(key, () => GlobalKey<NavigatorState>());return keys[key];}GlobalKey<NavigatorState> global(int k) {GlobalKey<NavigatorState> _key;if (k == null) {_key = key;} else {if (!keys.containsKey(k)) {throw 'Route id ($k) not found';}_key = keys[k];}if (_key.currentContext == null && !testMode) {throw """You are trying to use contextless navigation without a GetMaterialApp or Get.key. If you are testing your app, you can use: [Get.testMode = true], or if you are running your app on a physical device or emulator, you must exchange your [MaterialApp] for a [GetMaterialApp]. """;}return _key;}@Deprecated('''Since version 2.8 it is possible to access the properties\n[Get.arguments] and [Get.currentRoute] directly.\n[routeSettings] is useless and should not be used.''') RouteSettings get routeSettings => null;dynamic get arguments => routing.args;String get currentRoute => routing.current;String get previousRoute => routing.previous;bool get isSnackbarOpen => routing.isSnackbar;bool get isDialogOpen => routing.isDialog;bool get isBottomSheetOpen => routing.isBottomSheet;Route<dynamic> get rawRoute => routing.route;bool get isPopGestureEnable => defaultPopGesture;bool get isOpaqueRouteDefault => defaultOpaqueRoute;BuildContext get context => key?.currentContext;BuildContext get overlayContext => key?.currentState?.overlay?.context;ThemeData get theme {ThemeData _theme;if (context != null) _theme = Theme.of(context);return _theme;}WidgetsBinding get engine {if (WidgetsBinding.instance == null) WidgetsFlutterBinding();return WidgetsBinding.instance;}dynamic get window => ui.window;Locale get deviceLocale => ui.window.locale;double get pixelRatio => ui.window.devicePixelRatio;Size get size => ui.window.physicalSize / pixelRatio;double get width => size.width;double get height => size.height;double get statusBarHeight => ui.window.padding.top;double get bottomBarHeight => ui.window.padding.bottom;double get textScaleFactor => ui.window.textScaleFactor;TextTheme get textTheme => theme?.textTheme;MediaQueryData get mediaQuery => MediaQuery.of(context);bool get isDarkMode => (theme.brightness == Brightness.dark);bool get isPlatformDarkMode => (ui.window.platformBrightness == Brightness.dark);Color get iconColor => theme?.iconTheme?.color;FocusNode get focusScope => FocusManager.instance.primaryFocus;GlobalKey<NavigatorState> get key => getxController?.key;Map<int, GlobalKey<NavigatorState>> get keys => getxController?.keys;GetMaterialController get rootController => getxController;bool get defaultPopGesture => getxController.defaultPopGesture;bool get defaultOpaqueRoute => getxController.defaultOpaqueRoute;Transition get defaultTransition => getxController.defaultTransition;Duration get defaultTransitionDuration => getxController.defaultTransitionDuration;Curve get defaultTransitionCurve => getxController.defaultTransitionCurve;Curve get defaultDialogTransitionCurve => getxController.defaultDialogTransitionCurve;Duration get defaultDialogTransitionDuration => getxController.defaultDialogTransitionDuration;Routing get routing => getxController.routing;Map<String, String> get parameters => getxController.parameters;set parameters(Map<String, String> newParameters) => getxController.parameters = newParameters;ParseRouteTree get routeTree => getxController.routeTree;set routeTree(ParseRouteTree tree) => getxController.routeTree = tree;CustomTransition get customTransition => getxController.customTransition;set customTransition(CustomTransition newTransition) => getxController.customTransition = newTransition;bool get testMode => getxController.testMode;set testMode(bool isTest) => getxController.testMode = isTest;static GetMaterialController getxController = GetMaterialController();}extension Inst on GetInterface {void lazyPut<S>(InstanceBuilderCallback<S> builder, {String tag, bool fenix = false}) => GetInstance().lazyPut<S>(builder, tag: tag, fenix: fenix);void printInstanceStack() => GetInstance().printInstanceStack();Future<S> putAsync<S>(AsyncInstanceBuilderCallback<S> builder, {String tag, bool permanent = false}) async => GetInstance().putAsync<S>(builder, tag: tag, permanent: permanent);void create<S>(InstanceBuilderCallback<S> builder, {String tag, bool permanent = true}) => GetInstance().create<S>(builder, tag: tag, permanent: permanent);S find<S>({String tag}) => GetInstance().find<S>(tag: tag);S put<S>(S dependency, {String tag, bool permanent = false, InstanceBuilderCallback<S> builder}) => GetInstance().put<S>(dependency, tag: tag, permanent: permanent);bool reset({bool clearFactory = true, bool clearRouteBindings = true}) => GetInstance().reset(clearFactory: clearFactory, clearRouteBindings: clearRouteBindings);Future<bool> delete<S>({String tag, bool force = false}) async => GetInstance().delete<S>(tag: tag, force: force);bool isRegistered<S>({String tag}) => GetInstance().isRegistered<S>(tag: tag);bool isPrepared<S>({String tag}) => GetInstance().isPrepared<S>(tag: tag);}extension StringExtension on String {RxString get obs => RxString(this);}extension IntExtension on int {RxInt get obs => RxInt(this);}extension DoubleExtension on double {RxDouble get obs => RxDouble(this);}extension BoolExtension on bool {RxBool get obs => RxBool(this);}extension RxT<T> on T {Rx<T> get obs => Rx<T>(this);}extension ListExtension<E> on List<E> {RxList<E> get obs => RxList<E>(this);void addNonNull(E item) {if (item != null) add(item);}void addAllNonNull(Iterable<E> item) {if (item != null) addAll(item);}void addIf(dynamic condition, E item) {if (condition is Condition) condition = condition();if (condition is bool && condition) add(item);}void addAllIf(dynamic condition, Iterable<E> items) {if (condition is Condition) condition = condition();if (condition is bool && condition) addAll(items);}void assign(E item) {if (this is RxList) (this as RxList)._value ??= <E>[];clear();add(item);}void assignAll(Iterable<E> items) {if (this is RxList) (this as RxList)._value ??= <E>[];clear();addAll(items);}}extension MapExtension<K, V> on Map<K, V> {RxMap<K, V> get obs => RxMap<K, V>(this);void addIf(dynamic condition, K key, V value) {if (condition is Condition) condition = condition();if (condition is bool && condition) this[key] = value;}void addAllIf(dynamic condition, Map<K, V> values) {if (condition is Condition) condition = condition();if (condition is bool && condition) addAll(values);}void assign(K key, V val) {if (this is RxMap) {final map = (this as RxMap);map._value ??= <K, V>{};map._value.clear();this[key] = val;} else {clear();this[key] = val;}}void assignAll(Map<K, V> val) {if (this is RxMap) {final map = (this as RxMap);if (map._value == val || map == val) return;map._value = val;map.refresh();} else {if (this == val) return;clear();addAll(val);}}}extension SetExtension<E> on Set<E> {RxSet<E> get obs {if (this != null) return RxSet<E>(<E>{})..addAllNonNull(this); return RxSet<E>(null);}void addNonNull(E item) {if (item != null) add(item);}void addAllNonNull(Iterable<E> item) {if (item != null) addAll(item);}void addIf(dynamic condition, E item) {if (condition is Condition) condition = condition();if (condition is bool && condition) add(item);}void addAllIf(dynamic condition, Iterable<E> items) {if (condition is Condition) condition = condition();if (condition is bool && condition) addAll(items);}void assign(E item) {if (this is RxSet) (this as RxSet)._value ??= <E>{};clear();add(item);}void assignAll(Iterable<E> items) {if (this is RxSet) (this as RxSet)._value ??= <E>{};clear();addAll(items);}}extension ReactiveT<T> on T {Value<T> get reactive => Value<T>(this);}extension StateExt<T> on StateMixin<T> {Widget obx(NotifierBuilder<T> widget, {Widget Function(String error) onError, Widget onLoading, Widget onEmpty}) {assert(widget != null);return SimpleBuilder(builder: (_) {if (status.isLoading) {return onLoading ?? const Center(child: CircularProgressIndicator());} else if (status.isError) {return onError != null ? onError(status.errorMessage) : Center(child: Text('A error occurred: ${status.errorMessage}'));} else if (status.isEmpty) {return onEmpty != null ? onEmpty : SizedBox.shrink();}return widget(value);});}}extension WatchEtx on GetxController {T watch<T extends GetxController>() {final instance = Get.find<T>();_GetBuilderState._currentState.watch(instance.update);return instance;}}extension FindExt on BuildContext {T find<T extends GetxController>() => GetBuilder.of<T>(this, rebuild: false);}extension ObserverEtx on BuildContext {T obs<T extends GetxController>() => GetBuilder.of<T>(this, rebuild: true);}extension ContextExtensionss on BuildContext {Size get mediaQuerySize => MediaQuery.of(this).size;double get height => mediaQuerySize.height;double get width => mediaQuerySize.width;double heightTransformer({double dividedBy = 1, double reducedBy = 0.0}) => (mediaQuerySize.height - ((mediaQuerySize.height / 100) * reducedBy)) / dividedBy;double widthTransformer({double dividedBy = 1, double reducedBy = 0.0}) => (mediaQuerySize.width - ((mediaQuerySize.width / 100) * reducedBy)) / dividedBy;double ratio({double dividedBy = 1, double reducedByW = 0.0, double reducedByH = 0.0}) => heightTransformer(dividedBy: dividedBy, reducedBy: reducedByH) / widthTransformer(dividedBy: dividedBy, reducedBy: reducedByW);ThemeData get theme => Theme.of(this);bool get isDarkMode => (theme.brightness == Brightness.dark);Color get iconColor => theme.iconTheme.color;TextTheme get textTheme => Theme.of(this).textTheme;EdgeInsets get mediaQueryPadding => MediaQuery.of(this).padding;MediaQueryData get mediaQuery => MediaQuery.of(this);EdgeInsets get mediaQueryViewPadding => MediaQuery.of(this).viewPadding;EdgeInsets get mediaQueryViewInsets => MediaQuery.of(this).viewInsets;Orientation get orientation => MediaQuery.of(this).orientation;bool get isLandscape => orientation == Orientation.landscape;bool get isPortrait => orientation == Orientation.portrait;double get devicePixelRatio => MediaQuery.of(this).devicePixelRatio;double get textScaleFactor => MediaQuery.of(this).textScaleFactor;double get mediaQueryShortestSide => mediaQuerySize.shortestSide;bool get showNavbar => (width > 800);bool get isPhone => (mediaQueryShortestSide < 600);bool get isSmallTablet => (mediaQueryShortestSide >= 600);bool get isLargeTablet => (mediaQueryShortestSide >= 720);bool get isTablet => isSmallTablet || isLargeTablet;T responsiveValue<T>({T mobile, T tablet, T desktop, T watch}) {var deviceWidth = mediaQuerySize.shortestSide;if (GetPlatform.isDesktop) deviceWidth = mediaQuerySize.width;if (deviceWidth >= 1200 && desktop != null) return desktop;if (deviceWidth >= 600 && tablet != null) return tablet;if (deviceWidth < 300 && watch != null) return watch;return mobile;}}extension Precision on double {double toPrecision(int fractionDigits) {var mod = math.pow(10, fractionDigits.toDouble()).toDouble();return ((this * mod).round().toDouble() / mod);}}extension GetDurationUtils on Duration {Future delay([FutureOr callback()]) async => Future.delayed(this, callback);}extension GetDynamicUtils<T> on T {@Deprecated('isNull is deprecated and cannot be used, use "==" operator') bool get isNull => GetUtils.isNull(this);bool get isBlank => GetUtils.isBlank(this);@Deprecated('isNullOrBlank is deprecated and cannot be used, use "isBlank" instead') bool get isNullOrBlank => GetUtils.isNullOrBlank(this);void printError({String info = '', Function logFunction = GetUtils.printFunction}) => logFunction('Error: ${this.runtimeType}', this, info, isError: true);void printInfo({String info = '', Function printFunction = GetUtils.printFunction}) => printFunction('Info: ${this.runtimeType}', this, info);}extension LoopEventsExt on GetInterface {Future<T> toEnd<T>(FutureOr<T> computation()) async {await Future.delayed(Duration.zero);final val = computation();return val;}FutureOr<T> asap<T>(T computation(), {bool Function() condition}) async {T val;if (condition == null || !condition()) {await Future.delayed(Duration.zero);val = computation();} else {val = computation();}return val;}}extension Trans on String {String get tr {if (Get.locale?.languageCode == null) return this;if (Get.translations.containsKey("${Get.locale.languageCode}_${Get.locale.countryCode}") && Get.translations["${Get.locale.languageCode}_${Get.locale.countryCode}"].containsKey(this)) {return Get.translations["${Get.locale.languageCode}_${Get.locale.countryCode}"][this];} else if (Get.translations.containsKey(Get.locale.languageCode) && Get.translations[Get.locale.languageCode].containsKey(this)) {return Get.translations[Get.locale.languageCode][this];} else if (Get.fallbackLocale != null) {final fallback = Get.fallbackLocale;final key = "${fallback.languageCode}_${fallback.countryCode}";if (Get.translations.containsKey(key) && Get.translations[key].containsKey(this)) return Get.translations[key][this];if (Get.translations.containsKey(fallback.languageCode) && Get.translations[fallback.languageCode].containsKey(this)) return Get.translations[fallback.languageCode][this];return this;} else {return this;}}String trArgs([List<String> args = const []]) {var key = tr;if (args.isNotEmpty) for (final arg in args) key = key.replaceFirst(RegExp(r'%s'), arg.toString());return key;}String trPlural([String pluralKey, int i, List<String> args = const []]) => i > 1 ? pluralKey.trArgs(args) : trArgs(args);String trParams([Map<String, String> params = const {}]) {var trans = tr;if (params.isNotEmpty) {params.forEach((key, value) => trans = trans.replaceAll('@$key', value));}return trans;}String trPluralParams([String pluralKey, int i, Map<String, String> params = const {}]) => i > 1 ? pluralKey.trParams(params) : trParams(params);}extension LocalesIntl on GetInterface {static final _intlHost = _IntlHost();ui.Locale get locale => _intlHost.locale;ui.Locale get fallbackLocale => _intlHost.fallbackLocale;set locale(ui.Locale newLocale) => _intlHost.locale = newLocale;set fallbackLocale(ui.Locale newLocale) => _intlHost.fallbackLocale = newLocale;Map<String, Map<String, String>> get translations => _intlHost.translations;void addTranslations(Map<String, Map<String, String>> tr) => translations.addAll(tr);void appendTranslations(Map<String, Map<String, String>> tr) => tr.forEach((key, map) => translations.containsKey(key) ? translations[key].addAll(map) : translations[key] = map);}extension GetNumUtils on num {bool isLowerThan(num b) => GetUtils.isLowerThan(this, b);bool isGreaterThan(num b) => GetUtils.isGreaterThan(this, b);bool isEqual(num b) => GetUtils.isEqual(this, b);Future delay([FutureOr callback()]) async => Future.delayed(Duration(milliseconds: (this * 1000).round()), callback);Duration get milliseconds => Duration(microseconds: (this * 1000).round());Duration get seconds => Duration(milliseconds: (this * 1000).round());Duration get minutes => Duration(seconds: (this * Duration.secondsPerMinute).round());Duration get hours => Duration(minutes: (this * Duration.minutesPerHour).round());Duration get days => Duration(hours: (this * Duration.hoursPerDay).round());}extension GetStringUtils on String {bool get isNum => GetUtils.isNum(this);bool get isNumericOnly => GetUtils.isNumericOnly(this);bool get isAlphabetOnly => GetUtils.isAlphabetOnly(this);bool get isBool => GetUtils.isBool(this);bool get isVectorFileName => GetUtils.isVector(this);bool get isImageFileName => GetUtils.isImage(this);bool get isAudioFileName => GetUtils.isAudio(this);bool get isVideoFileName => GetUtils.isVideo(this);bool get isTxtFileName => GetUtils.isTxt(this);bool get isDocumentFileName => GetUtils.isWord(this);bool get isExcelFileName => GetUtils.isExcel(this);bool get isPPTFileName => GetUtils.isPPT(this);bool get isAPKFileName => GetUtils.isAPK(this);bool get isPDFFileName => GetUtils.isPDF(this);bool get isHTMLFileName => GetUtils.isHTML(this);bool get isURL => GetUtils.isURL(this);bool get isEmail => GetUtils.isEmail(this);bool get isPhoneNumber => GetUtils.isPhoneNumber(this);bool get isDateTime => GetUtils.isDateTime(this);bool get isMD5 => GetUtils.isMD5(this);bool get isSHA1 => GetUtils.isSHA1(this);bool get isSHA256 => GetUtils.isSHA256(this);bool get isBinary => GetUtils.isBinary(this);bool get isIPv4 => GetUtils.isIPv4(this);bool get isIPv6 => GetUtils.isIPv6(this);bool get isHexadecimal => GetUtils.isHexadecimal(this);bool get isPalindrom => GetUtils.isPalindrom(this);bool get isPassport => GetUtils.isPassport(this);bool get isCurrency => GetUtils.isCurrency(this);bool get isCpf => GetUtils.isCpf(this);bool get isCnpj => GetUtils.isCnpj(this);bool isCaseInsensitiveContains(String b) => GetUtils.isCaseInsensitiveContains(this, b);bool isCaseInsensitiveContainsAny(String b) => GetUtils.isCaseInsensitiveContainsAny(this, b);String get capitalize => GetUtils.capitalize(this);String get capitalizeFirst => GetUtils.capitalizeFirst(this);String get removeAllWhitespace => GetUtils.removeAllWhitespace(this);String get camelCase => GetUtils.camelCase(this);String numericOnly({bool firstWordOnly = false}) => GetUtils.numericOnly(this, firstWordOnly: firstWordOnly);}extension WidgetPaddingX on Widget {Widget paddingAll(double padding) => Padding(padding: EdgeInsets.all(padding), child: this);Widget paddingSymmetric({double horizontal = 0.0, double vertical = 0.0}) => Padding(padding: EdgeInsets.symmetric(horizontal: horizontal, vertical: vertical), child: this);Widget paddingOnly({double left = 0.0, double top = 0.0, double right = 0.0, double bottom = 0.0}) => Padding(padding: EdgeInsets.only(top: top, left: left, right: right, bottom: bottom), child: this);Widget get paddingZero => Padding(padding: EdgeInsets.zero, child: this);}extension WidgetMarginX on Widget {Widget marginAll(double margin) => Container(margin: EdgeInsets.all(margin), child: this);Widget marginSymmetric({double horizontal = 0.0, double vertical = 0.0}) => Container(margin: EdgeInsets.symmetric(horizontal: horizontal, vertical: vertical), child: this);Widget marginOnly({double left = 0.0, double top = 0.0, double right = 0.0, double bottom = 0.0}) => Container(margin: EdgeInsets.only(top: top, left: left, right: right, bottom: bottom), child: this);Widget get marginZero => Container(margin: EdgeInsets.zero, child: this);}extension WidgetSliverBoxX on Widget {Widget get sliverBox => SliverToBoxAdapter(child: this);}
class GeneralPlatform {static bool get isWeb => true;static bool get isMacOS => _navigator.appVersion.contains('Mac OS') && !GeneralPlatform.isIOS;static bool get isWindows => _navigator.appVersion.contains('Win');static bool get isLinux => (_navigator.appVersion.contains('Linux') || _navigator.appVersion.contains('x11')) && !isAndroid;static bool get isAndroid => _navigator.appVersion.contains('Android ');static bool get isIOS => GetUtils.hasMatch(_navigator.platform, r'/iPad|iPhone|iPod/') || (_navigator.platform == 'MacIntel' && _navigator.maxTouchPoints > 1);static bool get isFuchsia => false;static bool get isDesktop => isMacOS || isWindows || isLinux;}class GetConnect extends GetConnectInterface {GetConnect({this.userAgent = 'getx-client', this.timeout = const Duration(seconds: 5), this.followRedirects = true, this.maxRedirects = 5, this.maxAuthRetries = 1, this.allowAutoSignedCert = false}) {$configureLifeCycle();}bool allowAutoSignedCert, followRedirects;String baseUrl, userAgent, defaultContentType = 'application/json; charset=utf-8';int maxRedirects, maxAuthRetries;Decoder defaultDecoder;Duration timeout;List<TrustedCertificate> trustedCertificates;GetHttpClient _httpClient;List<GetSocket> _sockets;@override List<GetSocket> get sockets => _sockets ??= <GetSocket>[];@override GetHttpClient get httpClient => _httpClient ??= GetHttpClient(userAgent: userAgent, timeout: timeout, followRedirects: followRedirects, maxRedirects: maxRedirects, maxAuthRetries: maxAuthRetries, allowAutoSignedCert: allowAutoSignedCert, baseUrl: baseUrl, trustedCertificates: trustedCertificates);@override Future<Response<T>> get<T>(String url, {Map<String, String> headers, String contentType, Map<String, dynamic> query, Decoder<T> decoder}) {_checkIfDisposed();return httpClient.get<T>(url, headers: headers, contentType: contentType, query: query, decoder: decoder);}@override Future<Response<T>> post<T>(String url, dynamic body, {String contentType, Map<String, String> headers, Map<String, dynamic> query, Decoder<T> decoder, Progress uploadProgress}) {_checkIfDisposed();return httpClient.post<T>(url, body: body, headers: headers, contentType: contentType, query: query, decoder: decoder, uploadProgress: uploadProgress);}@override Future<Response<T>> put<T>(String url, dynamic body, {String contentType, Map<String, String> headers, Map<String, dynamic> query, Decoder<T> decoder, Progress uploadProgress}) {_checkIfDisposed();return httpClient.put<T>(url, body: body, headers: headers, contentType: contentType, query: query, decoder: decoder, uploadProgress: uploadProgress);}@override Future<Response<T>> patch<T>(String url, dynamic body, {String contentType, Map<String, String> headers, Map<String, dynamic> query, Decoder<T> decoder, Progress uploadProgress}) {_checkIfDisposed();return httpClient.patch<T>(url, body: body, headers: headers, contentType: contentType, query: query, decoder: decoder, uploadProgress: uploadProgress);}@override Future<Response<T>> request<T>(String url, String method, {dynamic body, String contentType, Map<String, String> headers, Map<String, dynamic> query, Decoder<T> decoder, Progress uploadProgress}) {_checkIfDisposed();return httpClient.request<T>(url, method, body: body, headers: headers, contentType: contentType, query: query, decoder: decoder, uploadProgress: uploadProgress);}@override Future<Response<T>> delete<T>(String url, {Map<String, String> headers, String contentType, Map<String, dynamic> query, Decoder<T> decoder}) {_checkIfDisposed();return httpClient.delete(url, headers: headers, contentType: contentType, query: query, decoder: decoder);}@override GetSocket socket(String url, {Duration ping = const Duration(seconds: 5)}) {_checkIfDisposed(isHttp: false);final _socket = GetSocket(_concatUrl(url), ping: ping);sockets.add(_socket);return _socket;}String _concatUrl(String url) => (url == null) ? baseUrl : baseUrl == null? url : baseUrl + url;@override Future<GraphQLResponse<T>> query<T>(String query, {String url, Map<String, dynamic> variables, Map<String, String> headers}) async {try {final res = await post(_concatUrl(url), {'query': query, 'variables': variables}, headers: headers);final listError = res.body['errors'];if ((listError is List) && listError.isNotEmpty) return GraphQLResponse<T>(graphQLErrors: listError.map((e) => GraphQLError(code: e['extensions']['code']?.toString(), message: e['message']?.toString())).toList());return GraphQLResponse<T>(body: res.body['data'] as T);} on Exception catch (_) {return GraphQLResponse<T>(graphQLErrors: [GraphQLError(code: null, message: _.toString())]);}}@override Future<GraphQLResponse<T>> mutation<T>(String mutation, {String url, Map<String, dynamic> variables, Map<String, String> headers}) async {try {final res = await post(_concatUrl(url), {'query': mutation, 'variables': variables}, headers: headers);final listError = res.body['errors'];if ((listError is List) && listError.isNotEmpty) return GraphQLResponse<T>(graphQLErrors: listError.map((e) => GraphQLError(code: e['extensions']['code']?.toString(), message: e['message']?.toString())).toList());return GraphQLResponse<T>(body: res.body['data'] as T);} on Exception catch (_) {return GraphQLResponse<T>(graphQLErrors: [GraphQLError(code: null, message: _.toString())]);}}bool _isDisposed = false;bool get isDisposed => _isDisposed;void _checkIfDisposed({bool isHttp = true}) {if (_isDisposed) throw 'Can not emit events to disposed clients';}void dispose() {if (_sockets != null) {for (var socket in sockets) socket.close();_sockets?.clear();sockets = null;}if (_httpClient != null) httpClient.close();_httpClient = null;_isDisposed = true;}}class GetSocket extends BaseWebSocket {GetSocket(String url, {Duration ping = const Duration(seconds: 5), bool allowSelfSigned = true}) : super(url, ping: ping, allowSelfSigned: allowSelfSigned);}class BaseWebSocket {String url;html.WebSocket socket;SocketNotifier socketNotifier = SocketNotifier();Duration ping;bool allowSelfSigned, isDisposed = false;ConnectionStatus connectionStatus;Timer _t;BaseWebSocket(this.url, {this.ping = const Duration(seconds: 5), this.allowSelfSigned = true}) {url = url.startsWith('https') ? url.replaceAll('https:', 'wss:') : url.replaceAll('http:', 'ws:');}void connect() {try {connectionStatus = ConnectionStatus.connecting;socket = html.WebSocket(url);socket.onOpen.listen((e) {socketNotifier?.open();_t = Timer?.periodic(ping, (t) => socket.send(''));connectionStatus = ConnectionStatus.connected;});socket.onMessage.listen((event) => socketNotifier.notifyData(event.data));socket.onClose.listen((e) {_t?.cancel();connectionStatus = ConnectionStatus.closed;socketNotifier.notifyClose(Close(e.reason, e.code));});socket.onError.listen((event) {_t?.cancel();socketNotifier.notifyError(Close(event.toString(), 0));connectionStatus = ConnectionStatus.closed;});} on Exception catch (e) {_t?.cancel();socketNotifier.notifyError(Close(e.toString(), 500));connectionStatus = ConnectionStatus.closed;}}void onOpen(OpenSocket fn) => socketNotifier.open = fn;void onClose(CloseSocket fn) => socketNotifier.addCloses(fn);void onError(CloseSocket fn) => socketNotifier.addErrors(fn);void onMessage(MessageSocket fn) => socketNotifier.addMessages(fn);void on(String event, MessageSocket message) => socketNotifier.addEvents(event, message);void close([int status, String reason]) => socket?.close(status, reason);void send(dynamic data) {if (connectionStatus == ConnectionStatus.closed) connect();if (socket != null && socket.readyState == html.WebSocket.OPEN) {socket.send(data);} else {Get.log('WebSocket not connected, message $data not sent');}}void emit(String event, dynamic data) => send(jsonEncode({'type': event, 'data': data}));void dispose() {socketNotifier.dispose();socketNotifier = null;isDisposed = true;}}class GetHttpClient {String baseUrl, userAgent, defaultContentType = 'application/json; charset=utf-8';bool followRedirects;int maxRedirects, maxAuthRetries;Decoder defaultDecoder;Duration timeout;bool errorSafety = true;final HttpRequestBase _httpClient;final GetModifier _modifier;GetHttpClient({this.userAgent = 'getx-client', this.timeout = const Duration(seconds: 8), this.followRedirects = true, this.maxRedirects = 5, this.maxAuthRetries = 1, bool allowAutoSignedCert = false, this.baseUrl, List<TrustedCertificate> trustedCertificates}): _httpClient = HttpRequestImpl(allowAutoSignedCert: allowAutoSignedCert, trustedCertificates: trustedCertificates), _modifier = GetModifier();void addAuthenticator<T>(RequestModifier<T> auth) => _modifier.authenticator = auth as RequestModifier;void addRequestModifier<T>(RequestModifier<T> interceptor) => _modifier.addRequestModifier<T>(interceptor);void removeRequestModifier<T>(RequestModifier<T> interceptor) => _modifier.removeRequestModifier(interceptor);void addResponseModifier<T>(ResponseModifier<T> interceptor) => _modifier.addResponseModifier(interceptor);void removeResponseModifier<T>(ResponseModifier<T> interceptor) => _modifier.removeResponseModifier<T>(interceptor);Uri _createUri(String url, Map<String, dynamic> query) {if (baseUrl != null) url = baseUrl + url;final uri = Uri.parse(url);return (query != null) ? uri.replace(queryParameters: query) : uri;}Future<Request<T>> _requestWithBody<T>(String url, String contentType, dynamic body, String method, Map<String, dynamic> query, Decoder<T> decoder, Progress uploadProgress) async {List<int> bodyBytes;BodyBytesStream bodyStream;final headers = <String, String>{};headers['user-agent'] = userAgent;if (body is FormData) {bodyBytes = await body.toBytes();headers['content-length'] = bodyBytes.length.toString();headers['content-type'] = 'multipart/form-data; boundary=${body.boundary}';} else if (body is Map || body is List) {var jsonString = json.encode(body);bodyBytes = utf8.encode(jsonString);headers['content-length'] = bodyBytes.length.toString();headers['content-type'] = contentType ?? defaultContentType;if (contentType != null) if (contentType.toLowerCase() == 'application/x-www-form-urlencoded') jsonString = Uri.encodeQueryComponent(jsonString);} else if (body is String) {bodyBytes = utf8.encode(body);headers['content-length'] = bodyBytes.length.toString();headers['content-type'] = contentType ?? defaultContentType;} else if (body == null) {headers['content-type'] = contentType ?? defaultContentType;headers['content-length'] = '0';} else {if (!errorSafety) throw UnexpectedFormat('body cannot be ${body.runtimeType}');}if (bodyBytes != null) bodyStream = _trackProgress(bodyBytes, uploadProgress);final uri = _createUri(url, query);return Request<T>(method: method, url: uri, headers: headers, bodyBytes: bodyStream, contentLength: bodyBytes.length, followRedirects: followRedirects, maxRedirects: maxRedirects, decoder: decoder);}BodyBytesStream _trackProgress(List<int> bodyBytes, Progress uploadProgress) {var total = 0;var length = bodyBytes.length;var byteStream = Stream.fromIterable(bodyBytes.map((i) => [i])).transform<List<int>>(StreamTransformer.fromHandlers(handleData: (data, sink) {total += data.length;if (uploadProgress != null) uploadProgress(total / length * 100);sink.add(data);}));return BodyBytesStream(byteStream);}void _setSimpleHeaders(Map<String, String> headers, String contentType) {headers['content-type'] = contentType ?? defaultContentType;headers['user-agent'] = userAgent;}Future<Response<T>> _performRequest<T>(HandlerExecute<T> handler, {bool authenticate = false, int requestNumber = 1, Map<String, String> headers}) async {try {var request = await handler();headers?.forEach((key, value) => request.headers[key] = value);if (authenticate) await _modifier.authenticator(request);await _modifier.modifyRequest(request);var response = await _httpClient.send<T>(request);await _modifier.modifyResponse(request, response);if (HttpStatus.unauthorized == response.statusCode && _modifier.authenticator != null && requestNumber <= maxAuthRetries) {return _performRequest<T>(handler, authenticate: true, requestNumber: requestNumber + 1, headers: request.headers);} else if (HttpStatus.unauthorized == response.statusCode) {if (!errorSafety) throw UnauthorizedException(); return Response<T>(request: request, headers: response.headers, statusCode: response.statusCode, body: response.body, bodyBytes: response.bodyBytes, bodyString: response.bodyString, statusText: response.statusText);}return response;} on Exception catch (err) {if (!errorSafety) throw GetHttpException(err.toString());return Response<T>(request: null, headers: null, statusCode: null, body: null, statusText: "$err");}}Future<Request<T>> _get<T>(String url, String contentType, Map<String, dynamic> query, Decoder<T> decoder) {final headers = <String, String>{};_setSimpleHeaders(headers, contentType);final uri = _createUri(url, query);return Future.value(Request<T>(method: 'get', url: uri, headers: headers, decoder: decoder ?? (defaultDecoder as Decoder<T>)));}Future<Request<T>> _request<T>(String url, String method, {String contentType, @required dynamic body, @required Map<String, dynamic> query, Decoder<T> decoder, @required Progress uploadProgress}) => _requestWithBody<T>(url, contentType, body, method, query, decoder ?? (defaultDecoder as Decoder<T>), uploadProgress);Request<T> _delete<T>(String url, String contentType, Map<String, dynamic> query, Decoder<T> decoder) {final headers = <String, String>{};_setSimpleHeaders(headers, contentType);final uri = _createUri(url, query);return Request<T>(method: 'delete', url: uri, headers: headers, decoder: decoder ?? (defaultDecoder as Decoder<T>));}Future<Response<T>> patch<T>(String url, {dynamic body, String contentType, Map<String, String> headers, Map<String, dynamic> query, Decoder<T> decoder, Progress uploadProgress}) async {try {var response = await _performRequest<T>(() => _request<T>(url, 'patch', contentType: contentType, body: body, query: query, decoder: decoder, uploadProgress: uploadProgress), headers: headers);return response;} on Exception catch (e) {if (!errorSafety) throw GetHttpException(e.toString());return Future.value(Response<T>(statusText: 'Can not connect to server. Reason: $e'));}}Future<Response<T>> post<T>(String url, {dynamic body, String contentType, Map<String, String> headers, Map<String, dynamic> query, Decoder<T> decoder, Progress uploadProgress}) async {try {var response = await _performRequest<T>(() => _request<T>(url, 'post', contentType: contentType, body: body, query: query, decoder: decoder, uploadProgress: uploadProgress), headers: headers);return response;} on Exception catch (e) {if (!errorSafety) throw GetHttpException(e.toString());return Future.value(Response<T>(statusText: 'Can not connect to server. Reason: $e'));}}Future<Response<T>> request<T>(String url, String method, {dynamic body, String contentType, Map<String, String> headers, Map<String, dynamic> query, Decoder<T> decoder, Progress uploadProgress}) async {try {var response = await _performRequest<T>(() => _request<T>(url, method, contentType: contentType, query: query, body: body, decoder: decoder, uploadProgress: uploadProgress), headers: headers);return response;} on Exception catch (e) {if (!errorSafety) throw GetHttpException(e.toString());return Future.value(Response<T>(statusText: 'Can not connect to server. Reason: $e'));}}Future<Response<T>> put<T>(String url, {dynamic body, String contentType, Map<String, String> headers, Map<String, dynamic> query, Decoder<T> decoder, Progress uploadProgress}) async {try {var response = await _performRequest<T>(() => _request<T>(url, 'put', contentType: contentType, query: query, body: body, decoder: decoder, uploadProgress: uploadProgress), headers: headers);return response;} on Exception catch (e) {if (!errorSafety) throw GetHttpException(e.toString());return Future.value(Response<T>(statusText: 'Can not connect to server. Reason: $e'));}}Future<Response<T>> get<T>(String url, {Map<String, String> headers, String contentType, Map<String, dynamic> query, Decoder<T> decoder}) async {try {var response = await _performRequest<T>(() => _get<T>(url, contentType, query, decoder), headers: headers);return response;} on Exception catch (e) {if (!errorSafety) throw GetHttpException(e.toString());return Future.value(Response<T>(statusText: 'Can not connect to server. Reason: $e'));}}Future<Response<T>> delete<T>(String url, {Map<String, String> headers, String contentType, Map<String, dynamic> query, Decoder<T> decoder}) async {try {var response = await _performRequest<T>(() async => _delete<T>(url, contentType, query, decoder), headers: headers);return response;} on Exception catch (e) {if (!errorSafety) throw GetHttpException(e.toString());return Future.value(Response<T>(statusText: 'Can not connect to server. Reason: $e'));}}void close() => _httpClient.close();}class HttpStatus {HttpStatus(this.code);final int code;static const int continue_ = 100, switchingProtocols = 101, processing = 102, ok = 200, created = 201, accepted = 202, nonAuthoritativeInformation = 203, noContent = 204, resetContent = 205, partialContent = 206, multiStatus = 207, alreadyReported = 208, imUsed = 226, multipleChoices = 300, movedPermanently = 301, found = 302, movedTemporarily = 302, seeOther = 303, notModified = 304, useProxy = 305, temporaryRedirect = 307, permanentRedirect = 308, badRequest = 400, unauthorized = 401, paymentRequired = 402, forbidden = 403, notFound = 404, methodNotAllowed = 405, notAcceptable = 406, proxyAuthenticationRequired = 407, requestTimeout = 408, conflict = 409, gone = 410, lengthRequired = 411, preconditionFailed = 412, requestEntityTooLarge = 413, requestUriTooLong = 414, unsupportedMediaType = 415, requestedRangeNotSatisfiable = 416, expectationFailed = 417, misdirectedRequest = 421, unprocessableEntity = 422, locked = 423, failedDependency = 424, upgradeRequired = 426, preconditionRequired = 428, tooManyRequests = 429, requestHeaderFieldsTooLarge = 431, connectionClosedWithoutResponse = 444, unavailableForLegalReasons = 451, clientClosedRequest = 499, internalServerError = 500, notImplemented = 501, badGateway = 502, serviceUnavailable = 503, gatewayTimeout = 504, httpVersionNotSupported = 505, variantAlsoNegotiates = 506, insufficientStorage = 507, loopDetected = 508, notExtended = 510, networkAuthenticationRequired = 511, networkConnectTimeoutError = 599;bool get connectionError => code == null;bool get isUnauthorized => code == unauthorized;bool get isForbidden => code == forbidden;bool get isNotFound => code == notFound;bool get isServerError => between(internalServerError, networkConnectTimeoutError);bool between(int begin, int end) => !connectionError && code >= begin && code <= end;bool get isOk => between(200, 299);bool get hasError => !isOk;}class GraphQLResponse<T> extends Response<T> {final List<GraphQLError> graphQLErrors;GraphQLResponse({T body, this.graphQLErrors}) : super(body: body);}class Response<T> {const Response({this.request, this.statusCode, this.bodyBytes, this.bodyString, this.statusText = '', this.headers = const {}, this.body});final Request request;final Map<String, String> headers;final int statusCode;final String statusText;HttpStatus get status => HttpStatus(statusCode);bool get hasError => status.hasError;bool get isOk => !hasError;bool get unauthorized => status.isUnauthorized;final BodyBytesStream bodyBytes;final String bodyString;final T body;}class HeaderValue {String _value;Map<String, String> _parameters, _unmodifiableParameters;HeaderValue([this._value = '', Map<String, String> parameters]) {if (parameters != null) _parameters = HashMap<String, String>.from(parameters);}static HeaderValue parse(String value, {String parameterSeparator = ';', String valueSeparator, bool preserveBackslash = false}) => HeaderValue().._parse(value, parameterSeparator, valueSeparator, preserveBackslash);String get value => _value;void _ensureParameters() => _parameters ??= HashMap<String, String>();Map<String, String> get parameters {_ensureParameters();return _unmodifiableParameters ??= UnmodifiableMapView(_parameters);}@override String toString() {var stringBuffer = StringBuffer();stringBuffer.write(_value);if (parameters != null && parameters.isNotEmpty) _parameters.forEach((name, value) => stringBuffer..write('; ')..write(name)..write('=')..write(value));return stringBuffer.toString();}void _parse(String value, String parameterSeparator, String valueSeparator, bool preserveBackslash) {var index = 0;bool done() => index == value.length;void bump() {while (!done()) {if (value[index] != ' ' && value[index] != '\t') return;index++;}}String parseValue() {var start = index;while (!done()) {if (value[index] == ' ' || value[index] == '\t' || value[index] == valueSeparator || value[index] == parameterSeparator) break;index++;}return value.substring(start, index);}void expect(String expected) {if (done() || value[index] != expected) throw StateError('Failed to parse header value');index++;}void maybeExpect(String expected) {if (value[index] == expected) index++;}void parseParameters() {var parameters = HashMap<String, String>();_parameters = UnmodifiableMapView(parameters);String parseParameterName() {var start = index;while (!done()) {if (value[index] == ' ' || value[index] == '\t' || value[index] == '=' || value[index] == parameterSeparator || value[index] == valueSeparator) break;index++;}return value.substring(start, index).toLowerCase();} String parseParameterValue() {if (!done() && value[index] == '\"') {var stringBuffer = StringBuffer();index++;while (!done()) {if (value[index] == '\\') {if (index + 1 == value.length) throw StateError('Failed to parse header value');if (preserveBackslash && value[index + 1] != '\"') stringBuffer.write(value[index]);index++;} else if (value[index] == '\"') {index++;break;}stringBuffer.write(value[index]);index++;}return stringBuffer.toString();} else {var val = parseValue();return val == '' ? null : val;}}while (!done()) {bump();if (done()) return;var name = parseParameterName();bump();if (done()) {parameters[name] = null;return;}maybeExpect('=');bump();if (done()) {parameters[name] = null;return;}var valueParameter = parseParameterValue();if (name == 'charset' && valueParameter != null) valueParameter = valueParameter.toLowerCase();parameters[name] = valueParameter;bump();if (done()) return;if (value[index] == valueSeparator) return;expect(parameterSeparator);}}bump();_value = parseValue();bump();if (done()) return;maybeExpect(parameterSeparator);parseParameters();}}class Request<T> {final Map<String, String> headers;final Uri url;final Decoder<T> decoder;final String method;final int contentLength;final BodyBytesStream bodyBytes;final bool followRedirects;final int maxRedirects;final bool persistentConnection;final FormData files;const Request._({@required this.method, @required this.bodyBytes, @required this.url, @required this.headers, @required this.contentLength, @required this.followRedirects, @required this.maxRedirects, @required this.files, @required this.persistentConnection, @required this.decoder});factory Request({@required Uri url, @required String method, @required Map<String, String> headers, BodyBytesStream bodyBytes, bool followRedirects = true, int maxRedirects = 4, int contentLength, FormData files, bool persistentConnection = true, Decoder<T> decoder}) {assert(url != null);assert(method != null);assert(followRedirects != null);if (followRedirects) {assert(maxRedirects != null);assert(maxRedirects > 0);}return Request._(url: url, method: method, bodyBytes: bodyBytes ??= BodyBytesStream.fromBytes(const []), headers: Map.from(headers ??= <String, String>{}), followRedirects: followRedirects, maxRedirects: maxRedirects, contentLength: contentLength, files: files, persistentConnection: persistentConnection, decoder: decoder);}}class BodyBytesStream extends StreamView<List<int>> {BodyBytesStream(Stream<List<int>> stream) : super(stream);factory BodyBytesStream.fromBytes(List<int> bytes) => BodyBytesStream(Stream.fromIterable([bytes]));Future<Uint8List> toBytes() {var completer = Completer<Uint8List>();var sink = ByteConversionSink.withCallback((bytes) => completer.complete(Uint8List.fromList(bytes)));listen(sink.add, onError: completer.completeError, onDone: sink.close, cancelOnError: true);return completer.future;}Future<String> bytesToString([Encoding encoding = utf8]) => encoding.decodeStream(this);}class FormData {FormData(Map<String, dynamic> map) : boundary = _getBoundary() {map.forEach((key, value) {if (value == null) return null;if (value is MultipartFile) {files.add(MapEntry(key, value));} else if (value is List<MultipartFile>) {files.addAll(value.map((e) => MapEntry(key, e)));} else if (value is List) {fields.addAll(value.map((e) => MapEntry(key, e.toString())));} else {fields.add(MapEntry(key, value.toString()));}});}static const int _maxBoundaryLength = 70;static String _getBoundary() {final _random = math.Random();return '$GET_BOUNDARY${String.fromCharCodes(List<int>.generate(_maxBoundaryLength - GET_BOUNDARY.length, (_) => boundaryCharacters[_random.nextInt(boundaryCharacters.length)], growable: false))}';}final String boundary;final fields = <MapEntry<String, String>>[]; final files = <MapEntry<String, MultipartFile>>[];String _fieldHeader(String name, String value) {var header = 'content-disposition: form-data; name="${browserEncode(name)}"';if (!isPlainAscii(value)) {header = '$header\r\n''content-type: text/plain; charset=utf-8\r\n''content-transfer-encoding: binary';}return '$header\r\n\r\n';}String _fileHeader(MapEntry<String, MultipartFile> file) {var header = 'content-disposition: form-data; name="${browserEncode(file.key)}"';if (file.value.filename != null) header = '$header; filename="${browserEncode(file.value.filename)}"';header = '$header\r\n''content-type: ${file.value.contentType}';return '$header\r\n\r\n';}int get length {var length = 0;for (final item in fields) length += '--'.length + _maxBoundaryLength + '\r\n'.length + utf8.encode(_fieldHeader(item.key, item.value)).length + utf8.encode(item.value).length + '\r\n'.length;for (var file in files) length += '--'.length + _maxBoundaryLength + '\r\n'.length + utf8.encode(_fileHeader(file)).length + file.value.length + '\r\n'.length;return length + '--'.length + _maxBoundaryLength + '--\r\n'.length;}Future<List<int>> toBytes() => BodyBytesStream(_encode()).toBytes();Stream<List<int>> _encode() async* {const line = [13, 10];final separator = utf8.encode('--$boundary\r\n');final close = utf8.encode('--$boundary--\r\n');for (var field in fields) {yield separator;yield utf8.encode(_fieldHeader(field.key, field.value));yield utf8.encode(field.value);yield line;}for (final file in files) {yield separator;yield utf8.encode(_fileHeader(file));yield* file.value.stream;yield line;}yield close;}}class MultipartFile {MultipartFile(dynamic data, {@required this.filename, this.contentType = 'application/octet-stream'}) : _bytes = fileToBytes(data) {_length = _bytes.length;_stream = BodyBytesStream.fromBytes(_bytes);}final List<int> _bytes;final String contentType;BodyBytesStream _stream;int _length;BodyBytesStream get stream => _stream;int get length => _length;final String filename;}class GetModifier<T> {final _requestModifiers = <RequestModifier>[];final _responseModifiers = <ResponseModifier>[];RequestModifier authenticator;void addRequestModifier<T>(RequestModifier<T> interceptor) => _requestModifiers.add(interceptor as RequestModifier);void removeRequestModifier<T>(RequestModifier<T> interceptor) => _requestModifiers.remove(interceptor);void addResponseModifier<T>(ResponseModifier<T> interceptor) => _responseModifiers.add(interceptor as ResponseModifier);void removeResponseModifier<T>(ResponseModifier<T> interceptor) => _requestModifiers.remove(interceptor);Future<void> modifyRequest(Request request) async {if (_requestModifiers.isNotEmpty) for (var interceptor in _requestModifiers) await interceptor(request);}Future<void> modifyResponse(Request request, Response response) async {if (_responseModifiers.isNotEmpty) for (var interceptor in _responseModifiers) await interceptor(request, response);}}class MockClient extends HttpRequestBase {final MockClientHandler _handler; MockClient(this._handler);@override Future<Response<T>> send<T>(Request<T> request) async {var requestBody = await request.bodyBytes.toBytes();var bodyBytes = BodyBytesStream.fromBytes(requestBody ?? const []);var response = await _handler(request);final stringBody = await bodyBytesToString(bodyBytes, response.headers);var mimeType = response.headers.containsKey('content-type') ? response.headers['content-type'] : '';final body = bodyDecoded<T>(request, stringBody, mimeType);return Response(headers: response.headers, request: request, statusCode: response.statusCode, statusText: response.statusText, bodyBytes: bodyBytes, body: body, bodyString: stringBody);}@override void close() {}}class HttpRequestImpl implements HttpRequestBase {HttpRequestImpl({bool allowAutoSignedCert = true, List<TrustedCertificate> trustedCertificates});final _xhrs = <html.HttpRequest>{}; bool withCredentials = false;@override Future<Response<T>> send<T>(Request<T> request) async {var bytes = await request.bodyBytes.toBytes();html.HttpRequest xhr;xhr = html.HttpRequest()..open(request.method, '${request.url}', async: true);_xhrs.add(xhr);xhr..responseType = 'blob'..withCredentials = withCredentials;request.headers.forEach(xhr.setRequestHeader);var completer = Completer<Response<T>>();xhr.onLoad.first.then((_) {var blob = xhr.response as html.Blob ?? html.Blob([]);var reader = html.FileReader();reader.onLoad.first.then((_) async {var bodyBytes = BodyBytesStream.fromBytes(reader.result as Uint8List);final stringBody = await bodyBytesToString(bodyBytes, xhr.responseHeaders);String contentType;contentType = xhr.responseHeaders.containsKey('content-type') ? xhr.responseHeaders['content-type'] : 'application/json';final body = bodyDecoded<T>(request, stringBody, contentType);final response = Response<T>(bodyBytes: bodyBytes, statusCode: xhr.status, request: request, headers: xhr.responseHeaders, statusText: xhr.statusText, body: body, bodyString: stringBody);completer.complete(response);});reader.onError.first.then((error) {completer.completeError(GetHttpException(error.toString(), request.url), StackTrace.current);});reader.readAsArrayBuffer(blob);});xhr.onError.first.then((_) => completer.completeError(GetHttpException('XMLHttpRequest error.', request.url), StackTrace.current));xhr.send(bytes);try {return await completer.future;} finally {_xhrs.remove(xhr);}}@override void close() {for (var xhr in _xhrs) xhr.abort();}}class GetHttpException implements Exception {final String message;final Uri uri;GetHttpException(this.message, [this.uri]);@override String toString() => message;}class GraphQLError {final String message, code;GraphQLError({this.code, this.message});@override String toString() => 'GETCONNECT ERROR:\n\tcode:$code\n\tmessage:$message';}class UnauthorizedException implements Exception {@override String toString() => 'Operation Unauthorized';}class UnexpectedFormat implements Exception {final String message;UnexpectedFormat(this.message);@override String toString() => 'Unexpected format: $message';}class TrustedCertificate {final List<int> bytes;TrustedCertificate(this.bytes);}class Close {final String message; final int reason;Close(this.message, this.reason);@override String toString() => 'Closed by server [$reason => $message]!';}class SocketNotifier {var _onMessages = <MessageSocket>[];var _onEvents = <String, MessageSocket>{};var _onCloses = <CloseSocket>[];var _onErrors = <CloseSocket>[];OpenSocket open;void addMessages(MessageSocket socket) => _onMessages.add((socket));void addEvents(String event, MessageSocket socket) => _onEvents[event] = socket;void addCloses(CloseSocket socket) => _onCloses.add(socket);void addErrors(CloseSocket socket) => _onErrors.add((socket));void notifyData(dynamic data) {for (var item in _onMessages) item(data);if (data is String) _tryOn(data);}void notifyClose(Close err) {for (var item in _onCloses) item(err);}void notifyError(Close err) {for (var item in _onErrors) item(err);}void _tryOn(String message) {try {var msg = jsonDecode(message);final event = msg['type'];final data = msg['data'];if (_onEvents.containsKey(event)) _onEvents[event](data);} on Exception catch (_) {return;}}void dispose() {_onMessages = null;_onEvents = null;_onCloses = null;_onErrors = null;}}class _GetImpl extends GetInterface {}class BindingsBuilder<T> extends Bindings {final BindingBuilderCallback builder;factory BindingsBuilder.put(InstanceBuilderCallback<T> builder, {String tag, bool permanent = false}) => BindingsBuilder(() => GetInstance().put<T>(builder(), tag: tag, permanent: permanent));BindingsBuilder(this.builder);@override void dependencies() {builder();}}class InstanceInfo {final bool isPermanent;final bool isSingleton;bool get isCreate => !isSingleton;final bool isRegistered;final bool isPrepared;final bool isInit;const InstanceInfo({@required this.isPermanent, @required this.isSingleton, @required this.isRegistered, @required this.isPrepared, @required this.isInit});}class GetInstance {factory GetInstance() => _getInstance ??= GetInstance._();const GetInstance._();static GetInstance _getInstance;T call<T>() => find<T>();static final Map<String, _InstanceBuilderFactory> _singl = {};static final Map<String, String> _routesKey = {};static final Map<String, HashSet<Function>> _routesByCreate = {};void lazyPut<S>(InstanceBuilderCallback<S> builder, {String tag, bool fenix}) => _insert(isSingleton: true, name: tag, permanent: fenix ?? Get.smartManagement == SmartManagement.keepFactory, builder: builder);void printInstanceStack() => Get.log(_routesKey.toString());void injector<S>(InjectorBuilderCallback<S> fn, {String tag, bool fenix = false}) => lazyPut(() => fn(this), tag: tag, fenix: fenix);Future<S> putAsync<S>(AsyncInstanceBuilderCallback<S> builder, {String tag, bool permanent = false}) async => put<S>(await builder(), tag: tag, permanent: permanent);S put<S>(S dependency, {String tag, bool permanent = false, @deprecated InstanceBuilderCallback<S> builder}) {_insert(isSingleton: true, name: tag, permanent: permanent, builder: builder ?? (() => dependency));return find<S>(tag: tag);}void create<S>(InstanceBuilderCallback<S> builder, {String tag, bool permanent = true}) => _insert(isSingleton: false, name: tag, builder: builder, permanent: permanent);void _insert<S>({bool isSingleton, String name, bool permanent = false, InstanceBuilderCallback<S> builder}) {assert(builder != null);final key = _getKey(S, name);_singl.putIfAbsent(key, () => _InstanceBuilderFactory<S>(isSingleton, builder, permanent, false));}void removeDependencyByRoute(String routeName) {final keysToRemove = <String>[];_routesKey.forEach((key, value) {if (value == routeName) keysToRemove.add(key);});if (_routesByCreate.containsKey(routeName)) {for (final onClose in _routesByCreate[routeName]) if (onClose != null) onClose();_routesByCreate[routeName].clear();_routesByCreate.remove(routeName);}for (final element in keysToRemove) delete(key: element);for (final element in keysToRemove) _routesKey?.remove(element);keysToRemove.clear();}S _initDependencies<S>({String name}) {final key = _getKey(S, name);final isInit = _singl[key].isInit;S i;if (!isInit) {i = _startController<S>(tag: name);if (_singl[key].isSingleton) {_singl[key].isInit = true; if (Get.smartManagement != SmartManagement.onlyBuilder) _registerRouteInstance<S>(tag: name);}}return i;}void _registerRouteInstance<S>({String tag}) => _routesKey.putIfAbsent(_getKey(S, tag), () => Get.reference);InstanceInfo getInstanceInfo<S>({String tag}) {final build = _getDependency<S>(tag: tag);return InstanceInfo(isPermanent: build?.permanent, isSingleton: build?.isSingleton, isRegistered: isRegistered<S>(tag: tag), isPrepared: !(build?.isInit ?? true), isInit: build?.isInit);}_InstanceBuilderFactory _getDependency<S>({String tag, String key}) {final newKey = key ?? _getKey(S, tag);if (!_singl.containsKey(newKey)) {Get.log('Instance "$newKey" is not registered.', isError: true);return null;} else {return _singl[newKey];}}S _startController<S>({String tag}) {final key = _getKey(S, tag);final i = _singl[key].getDependency() as S;if (i is GetLifeCycleBase) {if (i.onStart != null) {i.onStart(); Get.log('"$key" has been initialized');}if (!_singl[key].isSingleton && i.onDelete != null) {_routesByCreate[Get.reference] ??= HashSet<Function>(); _routesByCreate[Get.reference].add(i.onDelete);}}return i;}S putOrFind<S>(InstanceBuilderCallback<S> dep, {String tag}) {final key = _getKey(S, tag);if (_singl.containsKey(key)) return _singl[key].getDependency() as S;return GetInstance().put(dep(), tag: tag);}S find<S>({String tag}) {final key = _getKey(S, tag);if (isRegistered<S>(tag: tag)) {if (_singl[key] == null) {(tag == null) ? throw 'Class "$S" is not registered' : throw 'Class "$S" with tag "$tag" is not registered';}final i = _initDependencies<S>(name: tag);return i ?? _singl[key].getDependency() as S;} else {throw '"$S" not found. You need to call "Get.put($S())" or "Get.lazyPut(()=>$S())"';}}String _getKey(Type type, String name) => name == null ? type.toString() : type.toString() + name;bool reset({bool clearFactory = true, bool clearRouteBindings = true}) {if (clearRouteBindings) _routesKey.clear();_singl.clear();return true;}bool delete<S>({String tag, String key, bool force = false}) {final newKey = key ?? _getKey(S, tag);if (!_singl.containsKey(newKey)) {Get.log('Instance "$newKey" already removed.', isError: true);return false;}final builder = _singl[newKey];if (builder.permanent && !force) {Get.log('"$newKey" has been marked as permanent, SmartManagement is not authorized to delete it.', isError: true);return false;}final i = builder.dependency;if (i is GetxServiceMixin && !force) return false;if (i is GetLifeCycleBase && i.onDelete != null) {i.onDelete();Get.log('"$newKey" onDelete() called');}_singl.remove(newKey);(_singl.containsKey(newKey)) ? Get.log('Error removing object "$newKey"', isError: true) : Get.log('"$newKey" deleted from memory');return true;}void reloadAll({bool force = false}) {_singl.forEach((key, value) {if (value.permanent && !force) {Get.log('Instance "$key" is permanent. Skipping reload');} else {value.dependency = null;value.isInit = false;Get.log('Instance "$key" was reloaded.');}});}void reload<S>({String tag, String key, bool force = false}) {final newKey = key ?? _getKey(S, tag);final builder = _getDependency<S>(tag: tag, key: newKey);if (builder == null) return;if (builder.permanent && !force) {Get.log('''Instance "$newKey" is permanent. Use [force = true] to force the restart.''', isError: true);return;}builder.dependency = null;builder.isInit = false;Get.log('Instance "$newKey" was restarted.');}bool isRegistered<S>({String tag}) => _singl.containsKey(_getKey(S, tag));bool isPrepared<S>({String tag}) {final newKey = _getKey(S, tag);final builder = _getDependency<S>(tag: tag, key: newKey);if (builder == null) return false;if (!builder.isInit) return true;return false;}}class _InstanceBuilderFactory<S> {S dependency;InstanceBuilderCallback<S> builderFunc;bool permanent = false, isInit = false, isSingleton;_InstanceBuilderFactory(this.isSingleton, this.builderFunc, this.permanent, this.isInit);S getDependency() => isSingleton ? dependency ??= builderFunc() : builderFunc();}class _InternalFinalCallback<T> {ValueUpdater<T> _callback;_InternalFinalCallback({ValueUpdater<T> callback}) : _callback = callback;T call() => _callback.call();}class GetModalBottomSheetRoute<T> extends PopupRoute<T> {GetModalBottomSheetRoute({this.builder, this.theme, this.barrierLabel, this.backgroundColor, this.isPersistent, this.elevation, this.shape, this.removeTop = true, this.clipBehavior, this.modalBarrierColor, this.isDismissible = true, this.enableDrag = true, @required this.isScrollControlled, RouteSettings settings, this.enterBottomSheetDuration = const Duration(milliseconds: 250), this.exitBottomSheetDuration = const Duration(milliseconds: 200)}): assert(isScrollControlled != null), name = "BOTTOMSHEET: ${builder.hashCode}", assert(isDismissible != null), assert(enableDrag != null), super(settings: settings);final WidgetBuilder builder;final ThemeData theme;final double elevation;final ShapeBorder shape;final Clip clipBehavior;final Color backgroundColor, modalBarrierColor;final bool isDismissible, enableDrag, isPersistent, isScrollControlled;final String name;final Duration enterBottomSheetDuration, exitBottomSheetDuration;final bool removeTop;@override Duration get transitionDuration => Duration(milliseconds: 700);@override bool get barrierDismissible => isDismissible;@override final String barrierLabel;@override Color get barrierColor => modalBarrierColor ?? Colors.black54;AnimationController _animationController;@override AnimationController createAnimationController() {assert(_animationController == null);_animationController = BottomSheet.createAnimationController(navigator.overlay);_animationController.duration = enterBottomSheetDuration;_animationController.reverseDuration = exitBottomSheetDuration;return _animationController;}@override Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {final sheetTheme = theme?.bottomSheetTheme ?? Theme.of(context).bottomSheetTheme;Widget bottomSheet = MediaQuery.removePadding(context: context, removeTop: removeTop, child: Padding(padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), child: _GetModalBottomSheet<T>(route: this, backgroundColor: backgroundColor ?? sheetTheme?.modalBackgroundColor ?? sheetTheme?.backgroundColor, elevation: elevation ?? sheetTheme?.modalElevation ?? sheetTheme?.elevation, shape: shape, clipBehavior: clipBehavior, isScrollControlled: isScrollControlled, enableDrag: enableDrag)),);if (theme != null) bottomSheet = Theme(data: theme, child: bottomSheet);return bottomSheet;}}class _GetModalBottomSheet<T> extends StatefulWidget {const _GetModalBottomSheet({Key key, this.route, this.backgroundColor, this.elevation, this.shape, this.clipBehavior, this.isScrollControlled = false, this.enableDrag = true, this.isPersistent = false}): assert(isScrollControlled != null), assert(enableDrag != null), super(key: key);final bool isPersistent, isScrollControlled, enableDrag;final GetModalBottomSheetRoute<T> route;final Color backgroundColor;final double elevation;final ShapeBorder shape;final Clip clipBehavior;@override _GetModalBottomSheetState<T> createState() => _GetModalBottomSheetState<T>();}class _GetModalBottomSheetState<T> extends State<_GetModalBottomSheet<T>> {String _getRouteLabel(MaterialLocalizations localizations) {if ((Theme.of(context).platform == TargetPlatform.android) || (Theme.of(context).platform == TargetPlatform.fuchsia)) {return localizations.dialogLabel;} else {return '';}}@override Widget build(BuildContext context) {assert(debugCheckHasMediaQuery(context));assert(debugCheckHasMaterialLocalizations(context));final mediaQuery = MediaQuery.of(context);final localizations = MaterialLocalizations.of(context);final routeLabel = _getRouteLabel(localizations);return AnimatedBuilder(animation: widget.route.animation, builder: (context, child) {final animationValue = mediaQuery.accessibleNavigation ? 1.0 : widget.route.animation.value;return Semantics(scopesRoute: true, namesRoute: true, label: routeLabel, explicitChildNodes: true, child: ClipRect(child: CustomSingleChildLayout(delegate: _GetModalBottomSheetLayout(animationValue, widget.isScrollControlled), child: widget.isPersistent == false ? BottomSheet(animationController: widget.route._animationController, onClosing: () {if (widget.route.isCurrent) Navigator.pop(context);}, builder: widget.route.builder, backgroundColor: widget.backgroundColor, elevation: widget.elevation, shape: widget.shape, clipBehavior: widget.clipBehavior, enableDrag: widget.enableDrag) : Scaffold(bottomSheet: BottomSheet(animationController: widget.route._animationController, onClosing: () {}, builder: widget.route.builder, backgroundColor: widget.backgroundColor, elevation: widget.elevation, shape: widget.shape, clipBehavior: widget.clipBehavior, enableDrag: widget.enableDrag))),),);},);}}class _GetPerModalBottomSheet<T> extends StatefulWidget {const _GetPerModalBottomSheet({Key key, this.route, this.isPersistent, this.backgroundColor, this.elevation, this.shape, this.clipBehavior, this.isScrollControlled = false, this.enableDrag = true}): assert(isScrollControlled != null), assert(enableDrag != null), super(key: key);final bool isPersistent;final GetModalBottomSheetRoute<T> route;final bool isScrollControlled;final Color backgroundColor;final double elevation;final ShapeBorder shape;final Clip clipBehavior;final bool enableDrag;@override _GetPerModalBottomSheetState<T> createState() => _GetPerModalBottomSheetState<T>();}class _GetPerModalBottomSheetState<T> extends State<_GetPerModalBottomSheet<T>> {String _getRouteLabel(MaterialLocalizations localizations) {if ((Theme.of(context).platform == TargetPlatform.android) || (Theme.of(context).platform == TargetPlatform.fuchsia)) {return localizations.dialogLabel;} else {return '';}}@override Widget build(BuildContext context) {assert(debugCheckHasMediaQuery(context));assert(debugCheckHasMaterialLocalizations(context));final mediaQuery = MediaQuery.of(context);final localizations = MaterialLocalizations.of(context);final routeLabel = _getRouteLabel(localizations);return AnimatedBuilder(animation: widget.route.animation, builder: (context, child) {final animationValue = mediaQuery.accessibleNavigation ? 1.0 : widget.route.animation.value;return Semantics(scopesRoute: true, namesRoute: true, label: routeLabel, explicitChildNodes: true, child: ClipRect(child: CustomSingleChildLayout(delegate: _GetModalBottomSheetLayout(animationValue, widget.isScrollControlled), child: widget.isPersistent == false ? BottomSheet(animationController: widget.route._animationController, onClosing: () {if (widget.route.isCurrent) Navigator.pop(context);}, builder: widget.route.builder, backgroundColor: widget.backgroundColor, elevation: widget.elevation, shape: widget.shape, clipBehavior: widget.clipBehavior, enableDrag: widget.enableDrag): Scaffold(bottomSheet: BottomSheet(animationController: widget.route._animationController, onClosing: () {}, builder: widget.route.builder, backgroundColor: widget.backgroundColor, elevation: widget.elevation, shape: widget.shape, clipBehavior: widget.clipBehavior, enableDrag: widget.enableDrag)))));},);}}class _GetModalBottomSheetLayout extends SingleChildLayoutDelegate {_GetModalBottomSheetLayout(this.progress, this.isScrollControlled);final double progress;final bool isScrollControlled;@override BoxConstraints getConstraintsForChild(BoxConstraints constraints) => BoxConstraints(minWidth: constraints.maxWidth, maxWidth: constraints.maxWidth, minHeight: 0.0, maxHeight: isScrollControlled ? constraints.maxHeight : constraints.maxHeight * 9.0 / 16.0);@override Offset getPositionForChild(Size size, Size childSize) => Offset(0.0, size.height - childSize.height * progress);@override bool shouldRelayout(_GetModalBottomSheetLayout oldDelegate) => progress != oldDelegate.progress;}class GetDialogRoute<T> extends PopupRoute<T> {GetDialogRoute({@required RoutePageBuilder pageBuilder, bool barrierDismissible = true, String barrierLabel, Color barrierColor = const Color(0x80000000), Duration transitionDuration = const Duration(milliseconds: 200), RouteTransitionsBuilder transitionBuilder, RouteSettings settings}): assert(barrierDismissible != null), widget = pageBuilder, name = "DIALOG: ${pageBuilder.hashCode}", _barrierDismissible = barrierDismissible, _barrierLabel = barrierLabel, _barrierColor = barrierColor, _transitionDuration = transitionDuration, _transitionBuilder = transitionBuilder, super(settings: settings);final RoutePageBuilder widget;@override bool get barrierDismissible => _barrierDismissible;final bool _barrierDismissible;final String name;@override void dispose() {if (Get.smartManagement != SmartManagement.onlyBuilder) WidgetsBinding.instance.addPostFrameCallback((_) => GetInstance().removeDependencyByRoute(name));super.dispose();}@override String get barrierLabel => _barrierLabel;final String _barrierLabel;@override Color get barrierColor => _barrierColor;final Color _barrierColor;@override Duration get transitionDuration => _transitionDuration;final Duration _transitionDuration;final RouteTransitionsBuilder _transitionBuilder;@override Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) => Semantics(child: widget(context, animation, secondaryAnimation), scopesRoute: true, explicitChildNodes: true);@override Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {if (_transitionBuilder == null) return FadeTransition(opacity: CurvedAnimation(parent: animation, curve: Curves.linear), child: child);return _transitionBuilder(context, animation, secondaryAnimation, child);}}class GetCupertinoApp extends StatelessWidget {const GetCupertinoApp({Key key, this.theme, this.navigatorKey, this.home, this.routes = const <String, WidgetBuilder>{}, this.initialRoute, this.onGenerateRoute, this.onGenerateInitialRoutes, this.onUnknownRoute, this.navigatorObservers = const <NavigatorObserver>[], this.builder, this.translationsKeys, this.translations, this.textDirection, this.title = '', this.onGenerateTitle, this.color, this.customTransition, this.onInit, this.onDispose, this.locale, this.fallbackLocale, this.localizationsDelegates, this.localeListResolutionCallback, this.localeResolutionCallback, this.supportedLocales = const <Locale>[Locale('en', 'US')], this.showPerformanceOverlay = false, this.checkerboardRasterCacheImages = false, this.checkerboardOffscreenLayers = false, this.showSemanticsDebugger = false, this.debugShowCheckedModeBanner = true, this.shortcuts, this.smartManagement = SmartManagement.full, this.initialBinding, this.unknownRoute, this.routingCallback, this.defaultTransition, this.onReady, this.getPages, this.opaqueRoute, this.enableLog, this.logWriterCallback, this.popGesture, this.transitionDuration, this.defaultGlobalState, this.highContrastTheme, this.highContrastDarkTheme, this.actions}): assert(routes != null), assert(navigatorObservers != null), assert(title != null), assert(showPerformanceOverlay != null), assert(checkerboardRasterCacheImages != null), assert(checkerboardOffscreenLayers != null), assert(showSemanticsDebugger != null), assert(debugShowCheckedModeBanner != null), routeInformationProvider = null, routeInformationParser = null, routerDelegate = null, backButtonDispatcher = null, super(key: key);final GlobalKey<NavigatorState> navigatorKey;final Widget home;final Map<String, WidgetBuilder> routes;final RouteFactory onGenerateRoute;final InitialRouteListFactory onGenerateInitialRoutes;final RouteFactory onUnknownRoute;final List<NavigatorObserver> navigatorObservers;final TransitionBuilder builder;final String initialRoute, title;final GenerateAppTitle onGenerateTitle;final CustomTransition customTransition;final Color color;final Map<String, Map<String, String>> translationsKeys;final Translations translations;final TextDirection textDirection;final Locale locale, fallbackLocale;final Iterable<LocalizationsDelegate<dynamic>> localizationsDelegates;final LocaleListResolutionCallback localeListResolutionCallback;final LocaleResolutionCallback localeResolutionCallback;final Iterable<Locale> supportedLocales;final Map<LogicalKeySet, Intent> shortcuts;final ThemeData highContrastTheme, highContrastDarkTheme;final Map<Type, Action<Intent>> actions;final Function(Routing) routingCallback;final Transition defaultTransition;final VoidCallback onInit, onReady, onDispose;final LogWriterCallback logWriterCallback;final bool popGesture, enableLog, defaultGlobalState, opaqueRoute, showPerformanceOverlay, checkerboardRasterCacheImages, checkerboardOffscreenLayers, showSemanticsDebugger, debugShowCheckedModeBanner;final SmartManagement smartManagement;final Bindings initialBinding;final Duration transitionDuration;final List<GetPage> getPages;final GetPage unknownRoute;final RouteInformationProvider routeInformationProvider;final RouteInformationParser<Object> routeInformationParser;final RouterDelegate<Object> routerDelegate;final BackButtonDispatcher backButtonDispatcher;final CupertinoThemeData theme;const GetCupertinoApp.router({Key key, this.theme, this.routeInformationProvider, @required this.routeInformationParser, @required this.routerDelegate, this.backButtonDispatcher, this.builder, this.title = '', this.onGenerateTitle, this.color, this.highContrastTheme, this.highContrastDarkTheme, this.locale, this.localizationsDelegates, this.localeListResolutionCallback, this.localeResolutionCallback, this.supportedLocales = const <Locale>[Locale('en', 'US')], this.showPerformanceOverlay = false, this.checkerboardRasterCacheImages = false, this.checkerboardOffscreenLayers = false, this.showSemanticsDebugger = false, this.debugShowCheckedModeBanner = true, this.shortcuts, this.actions, this.customTransition, this.translationsKeys, this.translations, this.textDirection, this.fallbackLocale, this.routingCallback, this.defaultTransition, this.opaqueRoute, this.onInit, this.onReady, this.onDispose, this.enableLog, this.logWriterCallback, this.popGesture, this.smartManagement = SmartManagement.full, this.initialBinding, this.transitionDuration, this.defaultGlobalState, this.getPages, this.unknownRoute}): assert(routeInformationParser != null), assert(routerDelegate != null), assert(title != null), assert(showPerformanceOverlay != null), assert(checkerboardRasterCacheImages != null), assert(checkerboardOffscreenLayers != null), assert(showSemanticsDebugger != null), assert(debugShowCheckedModeBanner != null), navigatorObservers = null, navigatorKey = null, onGenerateRoute = null, home = null, onGenerateInitialRoutes = null, onUnknownRoute = null, routes = null, initialRoute = null, super(key: key);Route<dynamic> generator(RouteSettings settings) => PageRedirect(settings, unknownRoute).page();List<Route<dynamic>> initialRoutesGenerate(String name) => [PageRedirect(RouteSettings(name: name), unknownRoute).page()];@override Widget build(BuildContext context) => GetBuilder<GetMaterialController>(init: Get.rootController, dispose: (d) => onDispose?.call(), initState: (i) {Get.engine.addPostFrameCallback((timeStamp) => onReady?.call());if (locale != null) Get.locale = locale;if (fallbackLocale != null) Get.fallbackLocale = fallbackLocale;if (translations != null) {Get.addTranslations(translations.keys);} else if (translationsKeys != null) {Get.addTranslations(translationsKeys);}Get.customTransition = customTransition;initialBinding?.dependencies();Get.addPages(getPages);Get.smartManagement = smartManagement;onInit?.call();Get.config(enableLog: enableLog ?? Get.isLogEnable, logWriterCallback: logWriterCallback, defaultTransition: defaultTransition ?? Get.defaultTransition, defaultOpaqueRoute: opaqueRoute ?? Get.isOpaqueRouteDefault, defaultPopGesture: popGesture ?? Get.isPopGestureEnable, defaultDurationTransition: transitionDuration ?? Get.defaultTransitionDuration);}, builder: (_) => routerDelegate != null ? CupertinoApp.router(routerDelegate: routerDelegate, routeInformationParser: routeInformationParser, backButtonDispatcher: backButtonDispatcher, routeInformationProvider: routeInformationProvider, key: _.unikey, theme: theme, builder: (context, child) => Directionality(textDirection: textDirection ?? (rtlLanguages.contains(Get.locale?.languageCode) ? TextDirection.rtl : TextDirection.ltr), child: builder == null ? child : builder(context, child)), title: title ?? '', onGenerateTitle: onGenerateTitle, color: color, locale: Get.locale ?? locale, localizationsDelegates: localizationsDelegates, localeListResolutionCallback: localeListResolutionCallback, localeResolutionCallback: localeResolutionCallback, supportedLocales: supportedLocales ?? const <Locale>[Locale('en', 'US')], showPerformanceOverlay: showPerformanceOverlay ?? false, checkerboardRasterCacheImages: checkerboardRasterCacheImages ?? false, checkerboardOffscreenLayers: checkerboardOffscreenLayers ?? false, showSemanticsDebugger: showSemanticsDebugger ?? false, debugShowCheckedModeBanner: debugShowCheckedModeBanner ?? true, shortcuts: shortcuts) : CupertinoApp(key: _.unikey, theme: theme, navigatorKey: (navigatorKey == null ? Get.key : Get.addKey(navigatorKey)), home: home, routes: routes ?? const <String, WidgetBuilder>{}, initialRoute: initialRoute, onGenerateRoute: (getPages != null ? generator : onGenerateRoute), onGenerateInitialRoutes: (getPages == null || home != null) ? onGenerateInitialRoutes : initialRoutesGenerate, onUnknownRoute: onUnknownRoute, navigatorObservers: (navigatorObservers == null ? <NavigatorObserver>[GetObserver(routingCallback, Get.routing)] : <NavigatorObserver>[GetObserver(routingCallback, Get.routing)]..addAll(navigatorObservers)), builder: (context, child) => Directionality(textDirection: textDirection ?? (rtlLanguages.contains(Get.locale?.languageCode) ? TextDirection.rtl : TextDirection.ltr), child: builder == null ? child : builder(context, child)), title: title ?? '', onGenerateTitle: onGenerateTitle, color: color, locale: Get.locale ?? locale, localizationsDelegates: localizationsDelegates, localeListResolutionCallback: localeListResolutionCallback, localeResolutionCallback: localeResolutionCallback, supportedLocales: supportedLocales ?? const <Locale>[Locale('en', 'US')], showPerformanceOverlay: showPerformanceOverlay ?? false, checkerboardRasterCacheImages: checkerboardRasterCacheImages ?? false, checkerboardOffscreenLayers: checkerboardOffscreenLayers ?? false, showSemanticsDebugger: showSemanticsDebugger ?? false, debugShowCheckedModeBanner: debugShowCheckedModeBanner ?? true, shortcuts: shortcuts));}class GetMaterialApp extends StatelessWidget {const GetMaterialApp({Key key, this.navigatorKey, this.home, this.routes = const <String, WidgetBuilder>{}, this.initialRoute, this.onGenerateRoute, this.onGenerateInitialRoutes, this.onUnknownRoute, this.navigatorObservers = const <NavigatorObserver>[], this.builder, this.textDirection, this.title = '', this.onGenerateTitle, this.color, this.theme, this.darkTheme, this.themeMode = ThemeMode.system, this.locale, this.fallbackLocale, this.localizationsDelegates, this.localeListResolutionCallback, this.localeResolutionCallback, this.supportedLocales = const <Locale>[Locale('en', 'US')], this.debugShowMaterialGrid = false, this.showPerformanceOverlay = false, this.checkerboardRasterCacheImages = false, this.checkerboardOffscreenLayers = false, this.showSemanticsDebugger = false, this.debugShowCheckedModeBanner = true, this.shortcuts, this.customTransition, this.translationsKeys, this.translations, this.onInit, this.onReady, this.onDispose, this.routingCallback, this.defaultTransition, this.getPages, this.opaqueRoute, this.enableLog, this.logWriterCallback, this.popGesture, this.transitionDuration, this.defaultGlobalState, this.smartManagement = SmartManagement.full, this.initialBinding, this.unknownRoute, this.highContrastTheme, this.highContrastDarkTheme, this.actions}): assert(routes != null), assert(navigatorObservers != null), assert(title != null), assert(debugShowMaterialGrid != null), assert(showPerformanceOverlay != null), assert(checkerboardRasterCacheImages != null), assert(checkerboardOffscreenLayers != null), assert(showSemanticsDebugger != null), assert(debugShowCheckedModeBanner != null), routeInformationProvider = null, routeInformationParser = null, routerDelegate = null, backButtonDispatcher = null, super(key: key);final GlobalKey<NavigatorState> navigatorKey;final Widget home;final Map<String, WidgetBuilder> routes;final RouteFactory onGenerateRoute;final InitialRouteListFactory onGenerateInitialRoutes;final RouteFactory onUnknownRoute;final List<NavigatorObserver> navigatorObservers;final TransitionBuilder builder;final String title, initialRoute;final GenerateAppTitle onGenerateTitle;final ThemeData darkTheme, theme;final ThemeMode themeMode;final CustomTransition customTransition;final Color color;final Map<String, Map<String, String>> translationsKeys;final Translations translations;final TextDirection textDirection;final Locale locale, fallbackLocale;final Iterable<LocalizationsDelegate<dynamic>> localizationsDelegates;final LocaleListResolutionCallback localeListResolutionCallback;final LocaleResolutionCallback localeResolutionCallback;final Iterable<Locale> supportedLocales;final Map<LogicalKeySet, Intent> shortcuts;final ThemeData highContrastTheme;final ThemeData highContrastDarkTheme;final Map<Type, Action<Intent>> actions;final ValueChanged<Routing> routingCallback;final Transition defaultTransition;final VoidCallback onInit, onReady, onDispose;final LogWriterCallback logWriterCallback;final bool showPerformanceOverlay, checkerboardRasterCacheImages, checkerboardOffscreenLayers, showSemanticsDebugger, debugShowCheckedModeBanner, opaqueRoute, enableLog, popGesture, defaultGlobalState, debugShowMaterialGrid;final SmartManagement smartManagement;final Bindings initialBinding;final Duration transitionDuration;final List<GetPage> getPages;final GetPage unknownRoute;final RouteInformationProvider routeInformationProvider;final RouteInformationParser<Object> routeInformationParser;final RouterDelegate<Object> routerDelegate;final BackButtonDispatcher backButtonDispatcher;const GetMaterialApp.router({Key key, this.routeInformationProvider, @required this.routeInformationParser, @required this.routerDelegate, this.backButtonDispatcher, this.builder, this.title = '', this.onGenerateTitle, this.color, this.theme, this.darkTheme, this.highContrastTheme, this.highContrastDarkTheme, this.themeMode = ThemeMode.system, this.locale, this.localizationsDelegates, this.localeListResolutionCallback, this.localeResolutionCallback, this.supportedLocales = const <Locale>[Locale('en', 'US')], this.debugShowMaterialGrid = false, this.showPerformanceOverlay = false, this.checkerboardRasterCacheImages = false, this.checkerboardOffscreenLayers = false, this.showSemanticsDebugger = false, this.debugShowCheckedModeBanner = true, this.shortcuts, this.actions, this.customTransition, this.translationsKeys, this.translations, this.textDirection, this.fallbackLocale, this.routingCallback, this.defaultTransition, this.opaqueRoute, this.onInit, this.onReady, this.onDispose, this.enableLog, this.logWriterCallback, this.popGesture, this.smartManagement = SmartManagement.full, this.initialBinding, this.transitionDuration, this.defaultGlobalState, this.getPages, this.unknownRoute}): assert(routeInformationParser != null), assert(routerDelegate != null), assert(title != null), assert(debugShowMaterialGrid != null), assert(showPerformanceOverlay != null), assert(checkerboardRasterCacheImages != null), assert(checkerboardOffscreenLayers != null), assert(showSemanticsDebugger != null), assert(debugShowCheckedModeBanner != null), navigatorObservers = null, navigatorKey = null, onGenerateRoute = null, home = null, onGenerateInitialRoutes = null, onUnknownRoute = null, routes = null, initialRoute = null, super(key: key);Route<dynamic> generator(RouteSettings settings) => PageRedirect(settings, unknownRoute).page();List<Route<dynamic>> initialRoutesGenerate(String name) => [PageRedirect(RouteSettings(name: name), unknownRoute).page()];@override Widget build(BuildContext context) => GetBuilder<GetMaterialController>(init: Get.rootController, dispose: (d) => onDispose?.call(), initState: (i) {Get.engine.addPostFrameCallback((timeStamp) => onReady?.call());if (locale != null) Get.locale = locale;if (fallbackLocale != null) Get.fallbackLocale = fallbackLocale;if (translations != null) {Get.addTranslations(translations.keys);} else if (translationsKeys != null) {Get.addTranslations(translationsKeys);}Get.customTransition = customTransition;initialBinding?.dependencies();Get.addPages(getPages);Get.smartManagement = smartManagement;onInit?.call();Get.config(enableLog: enableLog ?? Get.isLogEnable, logWriterCallback: logWriterCallback, defaultTransition: defaultTransition ?? Get.defaultTransition, defaultOpaqueRoute: opaqueRoute ?? Get.isOpaqueRouteDefault, defaultPopGesture: popGesture ?? Get.isPopGestureEnable, defaultDurationTransition: transitionDuration ?? Get.defaultTransitionDuration);}, builder: (_) => routerDelegate != null ? MaterialApp.router(routerDelegate: routerDelegate, routeInformationParser: routeInformationParser, backButtonDispatcher: backButtonDispatcher, routeInformationProvider: routeInformationProvider, key: _.unikey, builder: (context, child) => Directionality(textDirection: textDirection ?? (rtlLanguages.contains(Get.locale?.languageCode) ? TextDirection.rtl : TextDirection.ltr), child: builder == null ? child : builder(context, child)), title: title ?? '', onGenerateTitle: onGenerateTitle, color: color, theme: _.theme ?? theme ?? ThemeData.fallback(), darkTheme: darkTheme, themeMode: _.themeMode ?? themeMode ?? ThemeMode.system, locale: Get.locale ?? locale, localizationsDelegates: localizationsDelegates, localeListResolutionCallback: localeListResolutionCallback, localeResolutionCallback: localeResolutionCallback, supportedLocales: supportedLocales ?? const <Locale>[Locale('en', 'US')], debugShowMaterialGrid: debugShowMaterialGrid ?? false, showPerformanceOverlay: showPerformanceOverlay ?? false, checkerboardRasterCacheImages: checkerboardRasterCacheImages ?? false, checkerboardOffscreenLayers: checkerboardOffscreenLayers ?? false, showSemanticsDebugger: showSemanticsDebugger ?? false, debugShowCheckedModeBanner: debugShowCheckedModeBanner ?? true, shortcuts: shortcuts) : MaterialApp(key: _.unikey, navigatorKey: (navigatorKey == null ? Get.key : Get.addKey(navigatorKey)), home: home, routes: routes ?? const <String, WidgetBuilder>{}, initialRoute: initialRoute, onGenerateRoute: (getPages != null ? generator : onGenerateRoute), onGenerateInitialRoutes: (getPages == null || home != null) ? onGenerateInitialRoutes : initialRoutesGenerate, onUnknownRoute: onUnknownRoute, navigatorObservers: (navigatorObservers == null ? <NavigatorObserver>[GetObserver(routingCallback, Get.routing)] : <NavigatorObserver>[GetObserver(routingCallback, Get.routing)]..addAll(navigatorObservers)), builder: (context, child) => Directionality(textDirection: textDirection ?? (rtlLanguages.contains(Get.locale?.languageCode) ? TextDirection.rtl : TextDirection.ltr), child: builder == null ? child : builder(context, child)), title: title ?? '', onGenerateTitle: onGenerateTitle, color: color, theme: _.theme ?? theme ?? ThemeData.fallback(), darkTheme: darkTheme, themeMode: _.themeMode ?? themeMode ?? ThemeMode.system, locale: Get.locale ?? locale, localizationsDelegates: localizationsDelegates, localeListResolutionCallback: localeListResolutionCallback, localeResolutionCallback: localeResolutionCallback, supportedLocales: supportedLocales ?? const <Locale>[Locale('en', 'US')], debugShowMaterialGrid: debugShowMaterialGrid ?? false, showPerformanceOverlay: showPerformanceOverlay ?? false, checkerboardRasterCacheImages: checkerboardRasterCacheImages ?? false, checkerboardOffscreenLayers: checkerboardOffscreenLayers ?? false, showSemanticsDebugger: showSemanticsDebugger ?? false, debugShowCheckedModeBanner: debugShowCheckedModeBanner ?? true, shortcuts: shortcuts));}class RouteDecoder {final GetPage route;final Map<String, String> parameters;const RouteDecoder(this.route, this.parameters);}class ParseRouteTree {final _routes = <GetPage>[];RouteDecoder matchRoute(String name) {final uri = Uri.parse(name);final route = _findRoute(uri.path);final params = Map<String, String>.from(uri.queryParameters);final parsedParams = _parseParams(name, route?.path);if (parsedParams != null && parsedParams.isNotEmpty) params.addAll(parsedParams);return RouteDecoder(route, params);}void addRoutes(List<GetPage> getPages) {for (final route in getPages) addRoute(route);}void addRoute(GetPage route) {_routes.add(route);for (var page in _flattenPage(route)) addRoute(page);}List<GetPage> _flattenPage(GetPage route) {final result = <GetPage>[];if (route.children == null || route.children.isEmpty) return result;final parentPath = route.name;for (var page in route.children) {final pageMiddlewares = page.middlewares ?? <GetMiddleware>[];pageMiddlewares.addAll(route.middlewares ?? <GetMiddleware>[]);result.add(_addChild(page, parentPath, pageMiddlewares));final children = _flattenPage(page);for (var child in children) {pageMiddlewares.addAll(child.middlewares ?? <GetMiddleware>[]);result.add(_addChild(child, parentPath, pageMiddlewares));}}return result;}GetPage _addChild(GetPage origin, String parentPath, List<GetMiddleware> middlewares) => GetPage(name: parentPath + origin.name, page: origin.page, title: origin.title, alignment: origin.alignment, transition: origin.transition, binding: origin.binding, bindings: origin.bindings, curve: origin.curve, customTransition: origin.customTransition, fullscreenDialog: origin.fullscreenDialog, maintainState: origin.maintainState, opaque: origin.opaque, parameter: origin.parameter, popGesture: origin.popGesture, settings: origin.settings, transitionDuration: origin.transitionDuration, middlewares: middlewares);GetPage _findRoute(String name) => _routes.firstWhere((route) => route.path.regex.hasMatch(name), orElse: () => null);Map<String, String> _parseParams(String path, PathDecoded routePath) {final params = <String, String>{};Match paramsMatch = routePath.regex.firstMatch(path);for (var i = 0; i < routePath.keys.length; i++) {var param = Uri.decodeQueryComponent(paramsMatch[i + 1]);params[routePath.keys[i]] = param;}return params;}}class GetMaterialController extends GetxController {bool testMode = false;Key unikey;ThemeData theme;ThemeMode themeMode;bool defaultPopGesture = GetPlatform.isIOS, defaultOpaqueRoute = true;Transition defaultTransition;Duration defaultTransitionDuration = Duration(milliseconds: 300), defaultDialogTransitionDuration = Duration(milliseconds: 300);Curve defaultTransitionCurve = Curves.easeOutQuad, defaultDialogTransitionCurve = Curves.easeOutQuad;final routing = Routing();Map<String, String> parameters = {};ParseRouteTree routeTree;CustomTransition customTransition;GlobalKey<NavigatorState> key = GlobalKey<NavigatorState>();Map<int, GlobalKey<NavigatorState>> keys = {};void setTheme(ThemeData value) {theme = value;update();}void setThemeMode(ThemeMode value) {themeMode = value;update();}void restartApp() {unikey = UniqueKey();update();}}class Routing {String current, previous, removed;dynamic args;Route<dynamic> route;bool isBack, isSnackbar, isBottomSheet, isDialog;Routing({this.current = '', this.previous = '', this.args, this.removed = '', this.route, this.isBack, this.isSnackbar, this.isBottomSheet, this.isDialog});void update(void fn(Routing value)) => fn(this);}class _RouteData {final bool isGetPageRoute, isSnackbar, isBottomSheet, isDialog;final String name;_RouteData({@required this.name, @required this.isGetPageRoute, @required this.isSnackbar, @required this.isBottomSheet, @required this.isDialog});factory _RouteData.ofRoute(Route route) {return _RouteData(name: _extractRouteName(route), isGetPageRoute: route is GetPageRoute, isSnackbar: route is SnackRoute, isDialog: route is GetDialogRoute, isBottomSheet: route is GetModalBottomSheetRoute);}}class GetObserver extends NavigatorObserver {final Function(Routing) routing;GetObserver([this.routing, this._routeSend]);final Routing _routeSend;@override void didPush(Route route, Route previousRoute) {super.didPush(route, previousRoute);final newRoute = _RouteData.ofRoute(route);if (newRoute.isSnackbar) {Get.log("OPEN SNACKBAR");} else if (newRoute.isBottomSheet || newRoute.isDialog) {Get.log("OPEN ${newRoute.name}");} else if (newRoute.isGetPageRoute) {Get.log("GOING TO ROUTE ${newRoute.name}");}Get.reference = newRoute.name;_routeSend?.update((value) {if (route is PageRoute) value.current = newRoute.name ?? '';value.args = route?.settings?.arguments;value.route = route;value.isBack = false;value.removed = '';value.previous = _extractRouteName(previousRoute) ?? '';value.isSnackbar = newRoute.isSnackbar ? true : value.isSnackbar ?? false;value.isBottomSheet = newRoute.isBottomSheet ? true : value.isBottomSheet ?? false;value.isDialog = newRoute.isDialog ? true : value.isDialog ?? false;});if (routing != null) routing(_routeSend);}@override void didPop(Route route, Route previousRoute) {super.didPop(route, previousRoute);final currentRoute = _RouteData.ofRoute(route);final newRoute = _RouteData.ofRoute(previousRoute);if (currentRoute.isSnackbar) {Get.log("CLOSE SNACKBAR");} else if (currentRoute.isBottomSheet || currentRoute.isDialog) {Get.log("CLOSE ${currentRoute.name}");} else if (currentRoute.isGetPageRoute) {Get.log("CLOSE TO ROUTE ${currentRoute.name}");}Get.reference = newRoute.name;_routeSend?.update((value) {if (previousRoute is PageRoute) value.current = _extractRouteName(previousRoute) ?? '';value.args = route?.settings?.arguments;value.route = previousRoute;value.isBack = true;value.removed = '';value.previous = newRoute.name ?? '';value.isSnackbar = currentRoute.isSnackbar ? false : value.isSnackbar;value.isBottomSheet = currentRoute.isBottomSheet ? false : value.isBottomSheet;value.isDialog = currentRoute.isDialog ? false : value.isDialog;});routing?.call(_routeSend);}@override void didReplace({Route newRoute, Route oldRoute}) {super.didReplace(newRoute: newRoute, oldRoute: oldRoute);final newName = _extractRouteName(newRoute);final oldName = _extractRouteName(oldRoute);final currentRoute = _RouteData.ofRoute(oldRoute);Get.log("REPLACE ROUTE $oldName");Get.log("NEW ROUTE $newName");Get.reference = newName;_routeSend?.update((value) {if (newRoute is PageRoute) value.current = newName ?? '';value.args = newRoute?.settings?.arguments;value.route = newRoute;value.isBack = false;value.removed = '';value.previous = '$oldName';value.isSnackbar = currentRoute.isSnackbar ? false : value.isSnackbar;value.isBottomSheet = currentRoute.isBottomSheet ? false : value.isBottomSheet;value.isDialog = currentRoute.isDialog ? false : value.isDialog;});routing?.call(_routeSend);}@override void didRemove(Route route, Route previousRoute) {super.didRemove(route, previousRoute);final routeName = _extractRouteName(route);final currentRoute = _RouteData.ofRoute(route);Get.log("REMOVING ROUTE $routeName");_routeSend?.update((value) {value.route = previousRoute;value.isBack = false;value.removed = routeName ?? '';value.previous = routeName ?? '';value.isSnackbar = currentRoute.isSnackbar ? false : value.isSnackbar;value.isBottomSheet = currentRoute.isBottomSheet ? false : value.isBottomSheet;value.isDialog = currentRoute.isDialog ? false : value.isDialog;});routing?.call(_routeSend);}}class GetPageRoute<T> extends PageRoute<T> {GetPageRoute({RouteSettings settings, this.transitionDuration = const Duration(milliseconds: 300), this.opaque = true, this.parameter, this.curve, this.alignment, this.transition, this.popGesture, this.customTransition, this.barrierDismissible = false, this.barrierColor, this.binding, this.bindings, this.routeName, this.page, this.barrierLabel, this.maintainState = true, bool fullscreenDialog = false, this.middlewares}): assert(opaque != null), assert(barrierDismissible != null), assert(maintainState != null), assert(fullscreenDialog != null), reference = "$routeName: ${page.hashCode}", super(settings: settings, fullscreenDialog: fullscreenDialog);@override final Duration transitionDuration;final GetPageBuilder page;final String reference, routeName;final CustomTransition customTransition;final Bindings binding;final Map<String, String> parameter;final List<Bindings> bindings;@override final bool barrierDismissible;@override final bool opaque;final bool popGesture;final Transition transition;final Curve curve;final Alignment alignment;final List<GetMiddleware> middlewares;@override final Color barrierColor;@override final String barrierLabel;@override final bool maintainState;@override bool canTransitionTo(TransitionRoute<dynamic> nextRoute) => nextRoute is PageRoute && !nextRoute.fullscreenDialog;static bool _isPopGestureEnabled<T>(PageRoute<T> route) {if (route.isFirst || route.willHandlePopInternally || route.hasScopedWillPopCallback || route.fullscreenDialog || route.animation.status != AnimationStatus.completed || route.secondaryAnimation.status != AnimationStatus.dismissed || isPopGestureInProgress(route)) return false;return true;}static _CupertinoBackGestureController<T> _startPopGesture<T>(PageRoute<T> route) {assert(_isPopGestureEnabled(route));return _CupertinoBackGestureController<T>(navigator: route.navigator, controller: route.controller);}@override Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {Get.reference = reference;final middlewareRunner = MiddlewareRunner(middlewares);final bindingsToBind = middlewareRunner.runOnBindingsStart(bindings);binding?.dependencies();if (bindingsToBind != null) {for (final binding in bindingsToBind) binding.dependencies();}final pageToBuild = middlewareRunner.runOnPageBuildStart(page);return middlewareRunner.runOnPageBuilt(pageToBuild());}static bool isPopGestureInProgress(PageRoute<dynamic> route) => route.navigator.userGestureInProgress;bool get popGestureInProgress => isPopGestureInProgress(this);@override Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {final finalCurve = curve ?? Get.defaultTransitionCurve;final hasCurve = curve != null;if (fullscreenDialog && transition == null) return CupertinoFullscreenDialogTransition(primaryRouteAnimation: hasCurve ? CurvedAnimation(parent: animation, curve: finalCurve) : animation, secondaryRouteAnimation: secondaryAnimation, child: child, linearTransition: hasCurve);if (customTransition != null) return customTransition.buildTransition(context, finalCurve, alignment, animation, secondaryAnimation, popGesture ?? Get.defaultPopGesture ? _CupertinoBackGestureDetector<T>(enabledCallback: () => _isPopGestureEnabled<T>(this), onStartPopGesture: () => _startPopGesture<T>(this), child: child) : child);final iosAnimation = animation;animation = CurvedAnimation(parent: animation, curve: finalCurve);switch (transition ?? Get.defaultTransition) {case Transition.leftToRight:return SlideLeftTransition().buildTransitions(context, curve, alignment, animation, secondaryAnimation, popGesture ?? Get.defaultPopGesture ? _CupertinoBackGestureDetector<T>(enabledCallback: () => _isPopGestureEnabled<T>(this), onStartPopGesture: () => _startPopGesture<T>(this), child: child) : child);case Transition.downToUp:return SlideDownTransition().buildTransitions(context, curve, alignment, animation, secondaryAnimation, popGesture ?? Get.defaultPopGesture ? _CupertinoBackGestureDetector<T>(enabledCallback: () => _isPopGestureEnabled<T>(this), onStartPopGesture: () => _startPopGesture<T>(this), child: child) : child);case Transition.upToDown:return SlideTopTransition().buildTransitions(context, curve, alignment, animation, secondaryAnimation, popGesture ?? Get.defaultPopGesture ? _CupertinoBackGestureDetector<T>(enabledCallback: () => _isPopGestureEnabled<T>(this), onStartPopGesture: () => _startPopGesture<T>(this), child: child) : child);case Transition.noTransition:return popGesture ?? Get.defaultPopGesture ? _CupertinoBackGestureDetector<T>(enabledCallback: () => _isPopGestureEnabled<T>(this), onStartPopGesture: () => _startPopGesture<T>(this), child: child) : child;case Transition.rightToLeft:return SlideRightTransition().buildTransitions(context, curve, alignment, animation, secondaryAnimation, popGesture ?? Get.defaultPopGesture ? _CupertinoBackGestureDetector<T>(enabledCallback: () => _isPopGestureEnabled<T>(this), onStartPopGesture: () => _startPopGesture<T>(this), child: child) : child);case Transition.zoom:return ZoomInTransition().buildTransitions(context, curve, alignment, animation, secondaryAnimation, popGesture ?? Get.defaultPopGesture ? _CupertinoBackGestureDetector<T>(enabledCallback: () => _isPopGestureEnabled<T>(this), onStartPopGesture: () => _startPopGesture<T>(this), child: child) : child);case Transition.fadeIn:return FadeInTransition().buildTransitions(context, curve, alignment, animation, secondaryAnimation, popGesture ?? Get.defaultPopGesture ? _CupertinoBackGestureDetector<T>(enabledCallback: () => _isPopGestureEnabled<T>(this), onStartPopGesture: () => _startPopGesture<T>(this), child: child) : child);case Transition.rightToLeftWithFade:return RightToLeftFadeTransition().buildTransitions(context, curve, alignment, animation, secondaryAnimation, popGesture ?? Get.defaultPopGesture ? _CupertinoBackGestureDetector<T>(enabledCallback: () => _isPopGestureEnabled<T>(this), onStartPopGesture: () => _startPopGesture<T>(this), child: child) : child);case Transition.leftToRightWithFade:return LeftToRightFadeTransition().buildTransitions(context, curve, alignment, animation, secondaryAnimation, popGesture ?? Get.defaultPopGesture ? _CupertinoBackGestureDetector<T>(enabledCallback: () => _isPopGestureEnabled<T>(this), onStartPopGesture: () => _startPopGesture<T>(this), child: child) : child);case Transition.cupertino:return CupertinoPageTransitionsBuilder().buildTransitions(this, context, iosAnimation, secondaryAnimation, popGesture ?? Get.defaultPopGesture ? _CupertinoBackGestureDetector<T>(enabledCallback: () => _isPopGestureEnabled<T>(this), onStartPopGesture: () => _startPopGesture<T>(this), child: child) : child);case Transition.size:return SizeTransitions().buildTransitions(context, curve, alignment, animation, secondaryAnimation, popGesture ?? Get.defaultPopGesture ? _CupertinoBackGestureDetector<T>(enabledCallback: () => _isPopGestureEnabled<T>(this), onStartPopGesture: () => _startPopGesture<T>(this), child: child) : child);case Transition.fade:return FadeUpwardsPageTransitionsBuilder().buildTransitions(this, context, animation, secondaryAnimation, popGesture ?? Get.defaultPopGesture ? _CupertinoBackGestureDetector<T>(enabledCallback: () => _isPopGestureEnabled<T>(this), onStartPopGesture: () => _startPopGesture<T>(this), child: child) : child);case Transition.topLevel:return ZoomPageTransitionsBuilder().buildTransitions(this, context, animation, secondaryAnimation, popGesture ?? Get.defaultPopGesture ? _CupertinoBackGestureDetector<T>(enabledCallback: () => _isPopGestureEnabled<T>(this), onStartPopGesture: () => _startPopGesture<T>(this), child: child) : child);case Transition.native:return PageTransitionsTheme().buildTransitions(this, context, iosAnimation, secondaryAnimation, popGesture ?? Get.defaultPopGesture ? _CupertinoBackGestureDetector<T>(enabledCallback: () => _isPopGestureEnabled<T>(this), onStartPopGesture: () => _startPopGesture<T>(this), child: child) : child);default:if (Get.customTransition != null) return Get.customTransition.buildTransition(context, curve, alignment, animation, secondaryAnimation, child);return PageTransitionsTheme().buildTransitions(this, context, iosAnimation, secondaryAnimation, popGesture ?? Get.defaultPopGesture ? _CupertinoBackGestureDetector<T>(enabledCallback: () => _isPopGestureEnabled<T>(this), onStartPopGesture: () => _startPopGesture<T>(this), child: child) : child);}}@override void dispose() {super.dispose();if (Get.smartManagement != SmartManagement.onlyBuilder) {WidgetsBinding.instance.addPostFrameCallback((_) {if (Get.reference != reference) GetInstance().removeDependencyByRoute("$reference");});}final middlewareRunner = MiddlewareRunner(middlewares);middlewareRunner.runOnPageDispose();}}class _CupertinoBackGestureDetector<T> extends StatefulWidget {const _CupertinoBackGestureDetector({Key key, @required this.enabledCallback, @required this.onStartPopGesture, @required this.child}): assert(enabledCallback != null), assert(onStartPopGesture != null), assert(child != null), super(key: key);final Widget child;final ValueGetter<bool> enabledCallback;final ValueGetter<_CupertinoBackGestureController<T>> onStartPopGesture;@override _CupertinoBackGestureDetectorState<T> createState() => _CupertinoBackGestureDetectorState<T>();}class _CupertinoBackGestureDetectorState<T> extends State<_CupertinoBackGestureDetector<T>> {_CupertinoBackGestureController<T> _backGestureController;HorizontalDragGestureRecognizer _recognizer;@override void initState() {super.initState();_recognizer = HorizontalDragGestureRecognizer(debugOwner: this)..onStart = _handleDragStart..onUpdate = _handleDragUpdate..onEnd = _handleDragEnd..onCancel = _handleDragCancel;}@override void dispose() {_recognizer.dispose();super.dispose();}void _handleDragStart(DragStartDetails details) {assert(mounted);assert(_backGestureController == null);_backGestureController = widget.onStartPopGesture();}void _handleDragUpdate(DragUpdateDetails details) {assert(mounted);assert(_backGestureController != null);_backGestureController.dragUpdate(_convertToLogical(details.primaryDelta / context.size.width));}void _handleDragEnd(DragEndDetails details) {assert(mounted);assert(_backGestureController != null);_backGestureController.dragEnd(_convertToLogical(details.velocity.pixelsPerSecond.dx / context.size.width));_backGestureController = null;}void _handleDragCancel() {assert(mounted);_backGestureController?.dragEnd(0.0);_backGestureController = null;}void _handlePointerDown(PointerDownEvent event) {if (widget.enabledCallback()) _recognizer.addPointer(event);}double _convertToLogical(double value) {switch (Directionality.of(context)) {case TextDirection.rtl:return -value;case TextDirection.ltr:return value;}return null;}@override Widget build(BuildContext context) {assert(debugCheckHasDirectionality(context));var dragAreaWidth = Directionality.of(context) == TextDirection.ltr ? MediaQuery.of(context).padding.left : MediaQuery.of(context).padding.right;dragAreaWidth = math.max(dragAreaWidth, _kBackGestureWidth);return Stack(fit: StackFit.passthrough, children: <Widget>[widget.child, PositionedDirectional(start: 0.0, width: dragAreaWidth, top: 0.0, bottom: 0.0, child: Listener(onPointerDown: _handlePointerDown, behavior: HitTestBehavior.translucent))]);}}class _CupertinoBackGestureController<T> {_CupertinoBackGestureController({@required this.navigator, @required this.controller}): assert(navigator != null),assert(controller != null) {navigator.didStartUserGesture();}final AnimationController controller;final NavigatorState navigator;void dragUpdate(double delta) => controller.value -= delta;void dragEnd(double velocity) {const Curve animationCurve = Curves.fastLinearToSlowEaseIn;bool animateForward;if (velocity.abs() >= _kMinFlingVelocity) {animateForward = velocity <= 0;} else {animateForward = controller.value > 0.5;}if (animateForward) {final droppedPageForwardAnimationTime = math.min(ui.lerpDouble(_kMaxDroppedSwipePageForwardAnimationTime, 0, controller.value).floor(), _kMaxPageBackAnimationTime); controller.animateTo(1.0, duration: Duration(milliseconds: droppedPageForwardAnimationTime), curve: animationCurve);} else {navigator.pop(); if (controller.isAnimating) { final droppedPageBackAnimationTime = ui.lerpDouble(0, _kMaxDroppedSwipePageForwardAnimationTime, controller.value).floor(); controller.animateBack(0.0, duration: Duration(milliseconds: droppedPageBackAnimationTime), curve: animationCurve); }}if (controller.isAnimating) {AnimationStatusListener animationStatusCallback; animationStatusCallback = (status) { navigator.didStopUserGesture(); controller.removeStatusListener(animationStatusCallback); }; controller.addStatusListener(animationStatusCallback);} else {navigator.didStopUserGesture();}}}class LeftToRightFadeTransition {Widget buildTransitions(BuildContext context, Curve curve, Alignment alignment, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) => SlideTransition(position: Tween<Offset>(begin: const Offset(-1.0, 0.0), end: Offset.zero).animate(animation), child: FadeTransition(opacity: animation, child: SlideTransition(position: Tween<Offset>(begin: Offset.zero, end: const Offset(1.0, 0.0)).animate(secondaryAnimation), child: child)));}class RightToLeftFadeTransition {Widget buildTransitions(BuildContext context, Curve curve, Alignment alignment, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) => SlideTransition(position: Tween<Offset>(begin: const Offset(1.0, 0.0), end: Offset.zero).animate(animation), child: FadeTransition(opacity: animation, child: SlideTransition(position: Tween<Offset>(begin: Offset.zero, end: const Offset(-1.0, 0.0)).animate(secondaryAnimation), child: child)));}class NoTransition {Widget buildTransitions(BuildContext context, Curve curve, Alignment alignment, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) => child;}class FadeInTransition {Widget buildTransitions(BuildContext context, Curve curve, Alignment alignment, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) => FadeTransition(opacity: animation, child: child);}class SlideDownTransition {Widget buildTransitions(BuildContext context, Curve curve, Alignment alignment, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) => SlideTransition(position: Tween<Offset>(begin: Offset(0.0, 1.0), end: Offset.zero).animate(animation), child: child);}class SlideLeftTransition {Widget buildTransitions(BuildContext context, Curve curve, Alignment alignment, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) => SlideTransition(position: Tween<Offset>(begin: Offset(-1.0, 0.0), end: Offset.zero).animate(animation), child: child);}class SlideRightTransition {Widget buildTransitions(BuildContext context, Curve curve, Alignment alignment, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) => SlideTransition(position: Tween<Offset>(begin: Offset(1.0, 0.0), end: Offset.zero).animate(animation), child: child);}class SlideTopTransition {Widget buildTransitions(BuildContext context, Curve curve, Alignment alignment, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) => SlideTransition(position: Tween<Offset>(begin: Offset(0.0, -1.0), end: Offset.zero).animate(animation), child: child);}class ZoomInTransition {Widget buildTransitions(BuildContext context, Curve curve, Alignment alignment, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) => ScaleTransition(scale: animation, child: child);}class SizeTransitions {Widget buildTransitions(BuildContext context, Curve curve, Alignment alignment, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) => Align(alignment: Alignment.center, child: SizeTransition(sizeFactor: CurvedAnimation(parent: animation, curve: curve), child: child));}class PathDecoded {const PathDecoded(this.regex, this.keys);final RegExp regex;final List<String> keys;}class GetPage {final String title, name;final GetPageBuilder page;final Map<String, String> parameter;final Transition transition;final Curve curve;final Alignment alignment;final Bindings binding;final List<Bindings> bindings;final CustomTransition customTransition;final Duration transitionDuration;final bool maintainState, opaque, fullscreenDialog, popGesture;final RouteSettings settings;final List<GetPage> children;final List<GetMiddleware> middlewares;final PathDecoded path;GetPage({@required this.name, @required this.page, this.title, this.settings, this.maintainState = true, this.curve = Curves.linear, this.alignment, this.parameter, this.opaque = true, this.transitionDuration, this.popGesture, this.binding, this.bindings = const [], this.transition, this.customTransition, this.fullscreenDialog = false, this.children, this.middlewares}): path = _nameToRegex(name), assert(page != null), assert(name != null), assert(maintainState != null), assert(fullscreenDialog != null);static PathDecoded _nameToRegex(String path) {var keys = <String>[];String _replace(Match pattern) {var buffer = StringBuffer('(?:');if (pattern[1] != null) buffer.write('\.');buffer.write('([\\w%+-._~!\$&\'()*,;=:@]+))');if (pattern[3] != null) buffer.write('?');keys.add(pattern[2]);return "$buffer";}var stringPath = '$path/?'.replaceAllMapped(RegExp(r'(\.)?:(\w+)(\?)?'), _replace).replaceAll('//', '/');return PathDecoded(RegExp('^$stringPath\$'), keys);}GetPage copyWith({String name, GetPageBuilder page, bool popGesture, Map<String, String> parameter, String title, Transition transition, Curve curve, Alignment alignment, bool maintainState, bool opaque, Bindings binding, List<Bindings> bindings, CustomTransition customTransition, Duration transitionDuration, bool fullscreenDialog, RouteSettings settings, List<GetPage> children, List<GetMiddleware> middlewares}) => GetPage(name: name ?? this.name, page: page ?? this.page, popGesture: popGesture ?? this.popGesture, parameter: parameter ?? this.parameter, title: title ?? this.title, transition: transition ?? this.transition, curve: curve ?? this.curve, alignment: alignment ?? this.alignment, maintainState: maintainState ?? this.maintainState, opaque: opaque ?? this.opaque, binding: binding ?? this.binding, bindings: bindings ?? this.bindings, customTransition: customTransition ?? this.customTransition, transitionDuration: transitionDuration ?? this.transitionDuration, fullscreenDialog: fullscreenDialog ?? this.fullscreenDialog, settings: settings ?? this.settings, children: children ?? this.children, middlewares: middlewares ?? this.middlewares);}class GetMiddleware implements _RouteMiddleware {@override int priority = 0;GetMiddleware({this.priority});@override RouteSettings redirect(String route) => null;@override GetPage onPageCalled(GetPage page) => page;@override List<Bindings> onBindingsStart(List<Bindings> bindings) => bindings;@override GetPageBuilder onPageBuildStart(GetPageBuilder page) => page;@override Widget onPageBuilt(Widget page) => page;@override void onPageDispose() {}}class MiddlewareRunner {MiddlewareRunner(this._middlewares);final List<GetMiddleware> _middlewares;List<GetMiddleware> _getMiddlewares() {if (_middlewares != null) {_middlewares.sort((a, b) => a.priority.compareTo(b.priority));return _middlewares;}return <GetMiddleware>[];}GetPage runOnPageCalled(GetPage page) {_getMiddlewares().forEach((element) => page = element.onPageCalled(page));return page;}RouteSettings runRedirect(String route) {RouteSettings to;_getMiddlewares().forEach((element) => to = element.redirect(route));if (to != null) Get.log('Redirect to $to');return to;}List<Bindings> runOnBindingsStart(List<Bindings> bindings) {_getMiddlewares().forEach((element) => bindings = element.onBindingsStart(bindings));return bindings;}GetPageBuilder runOnPageBuildStart(GetPageBuilder page) {_getMiddlewares().forEach((element) => page = element.onPageBuildStart(page));return page;}Widget runOnPageBuilt(Widget page) {_getMiddlewares().forEach((element) => page = element.onPageBuilt(page));return page;}void runOnPageDispose() => _getMiddlewares().forEach((element) => element.onPageDispose());}class PageRedirect {GetPage route, unknownRoute;RouteSettings settings;bool isUnknown;PageRedirect(this.settings, this.unknownRoute, {this.isUnknown = false, this.route});GetPageRoute page() {while (needRecheck()) {}return isUnknown ? GetPageRoute(page: unknownRoute.page, parameter: unknownRoute.parameter, settings: RouteSettings(name: settings.name, arguments: settings.arguments), curve: unknownRoute.curve, opaque: unknownRoute.opaque, customTransition: unknownRoute.customTransition, binding: unknownRoute.binding, bindings: unknownRoute.bindings, transitionDuration: (unknownRoute.transitionDuration ?? Get.defaultTransitionDuration), transition: unknownRoute.transition, popGesture: unknownRoute.popGesture, fullscreenDialog: unknownRoute.fullscreenDialog, middlewares: unknownRoute.middlewares) : GetPageRoute(page: route.page, parameter: route.parameter, settings: RouteSettings(name: settings.name, arguments: settings.arguments), curve: route.curve, opaque: route.opaque, customTransition: route.customTransition, binding: route.binding, bindings: route.bindings, transitionDuration: (route.transitionDuration ?? Get.defaultTransitionDuration), transition: route.transition, popGesture: route.popGesture, fullscreenDialog: route.fullscreenDialog, middlewares: route.middlewares);}bool needRecheck() {final match = Get.routeTree.matchRoute(settings.name);Get.parameters = match?.parameters;if (match?.route == null) {isUnknown = true;return false;}final runner = MiddlewareRunner(match.route.middlewares);route = runner.runOnPageCalled(match.route);addPageParameter(route);if (match.route.middlewares == null || match.route.middlewares.isEmpty) return false;final newSettings = runner.runRedirect(settings.name);if (newSettings == null) return false;settings = newSettings;return true;}void addPageParameter(GetPage route) {if (route.parameter == null) return;if (Get.parameters == null) {Get.parameters = route.parameter;} else {final parameters = Get.parameters;parameters.addEntries(route.parameter.entries);Get.parameters = parameters;}}}class TransitionComponent {Widget buildChildWithTransition(BuildContext context, Curve curve, Alignment alignment, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) => child;}class SnackRoute<T> extends OverlayRoute<T> {Animation<double> _filterBlurAnimation;Animation<Color> _filterColorAnimation;SnackRoute({@required this.snack,RouteSettings settings}) : super(settings: settings) {_builder = Builder(builder: (_) => GestureDetector(child: snack, onTap: snack.onTap != null ? () => snack.onTap(snack) : null));_configureAlignment(snack.snackPosition);_snackbarStatus = snack.snackbarStatus;}_configureAlignment(SnackPosition snackPosition) {switch (snack.snackPosition) {case SnackPosition.TOP:{ _initialAlignment = Alignment(-1.0, -2.0); _endAlignment = Alignment(-1.0, -1.0); break; }case SnackPosition.BOTTOM:{ _initialAlignment = Alignment(-1.0, 2.0); _endAlignment = Alignment(-1.0, 1.0); break; }}}GetBar snack;Builder _builder;final Completer<T> _transitionCompleter = Completer<T>();SnackbarStatusCallback _snackbarStatus;Alignment _endAlignment, _initialAlignment;bool _wasDismissedBySwipe = false;bool _onTappedDismiss = false;Timer _timer;bool get opaque => false;@override Iterable<OverlayEntry> createOverlayEntries() {return <OverlayEntry>[if (snack.overlayBlur > 0.0) ...[OverlayEntry(builder: (context) => GestureDetector(onTap: () {if (snack.isDismissible && !_onTappedDismiss) {_onTappedDismiss = true; Get.back();}}, child: AnimatedBuilder(animation: _filterBlurAnimation, builder: (context, child) => BackdropFilter( filter: ui.ImageFilter.blur(sigmaX: _filterBlurAnimation.value, sigmaY: _filterBlurAnimation.value), child: Container(constraints: BoxConstraints.expand(), color: _filterColorAnimation.value), ))), maintainState: false, opaque: opaque),], OverlayEntry(builder: (context) {final Widget annotatedChild = Semantics(child: AlignTransition(alignment: _animation, child: snack.isDismissible ? _getDismissibleSnack(_builder) : _getSnack()), focused: false, container: true, explicitChildNodes: true);return annotatedChild;}, maintainState: false, opaque: opaque)];}String dismissibleKeyGen = "";Widget _getDismissibleSnack(Widget child) => Dismissible(direction: _getDismissDirection(), resizeDuration: null, confirmDismiss: (_) {if (currentStatus == SnackbarStatus.OPENING || currentStatus == SnackbarStatus.CLOSING) return Future.value(false);return Future.value(true);}, key: Key(dismissibleKeyGen), onDismissed: (_) {dismissibleKeyGen += "1";_cancelTimer();_wasDismissedBySwipe = true;if (isCurrent) {navigator.pop();} else {navigator.removeRoute(this);}}, child: _getSnack());Widget _getSnack() => Container(margin: snack.margin, child: _builder);DismissDirection _getDismissDirection() {if (snack.dismissDirection == SnackDismissDirection.HORIZONTAL) return DismissDirection.horizontal;if (snack.snackPosition == SnackPosition.TOP) return DismissDirection.up;return DismissDirection.down;}@override bool get finishedWhenPopped => _controller.status == AnimationStatus.dismissed;Animation<Alignment> _animation;AnimationController _controller;AnimationController createAnimationController() {assert(!_transitionCompleter.isCompleted, 'Cannot reuse a $runtimeType after disposing it.');assert(snack.animationDuration != null && snack.animationDuration >= Duration.zero);return AnimationController(duration: snack.animationDuration, debugLabel: debugLabel, vsync: navigator);}Animation<Alignment> createAnimation() {assert(!_transitionCompleter.isCompleted, 'Cannot reuse a $runtimeType after disposing it.');assert(_controller != null);return AlignmentTween(begin: _initialAlignment, end: _endAlignment).animate(CurvedAnimation(parent: _controller, curve: snack.forwardAnimationCurve, reverseCurve: snack.reverseAnimationCurve));}Animation<double> createBlurFilterAnimation() => Tween(begin: 0.0, end: snack.overlayBlur).animate(CurvedAnimation(parent: _controller, curve: Interval(0.0, 0.35, curve: Curves.easeInOutCirc)));Animation<Color> createColorFilterAnimation() => ColorTween(begin: Color(0x00000000), end: snack.overlayColor).animate(CurvedAnimation(parent: _controller, curve: Interval(0.0, 0.35, curve: Curves.easeInOutCirc)));T _result;SnackbarStatus currentStatus;void _handleStatusChanged(AnimationStatus status) {switch (status) {case AnimationStatus.completed:currentStatus = SnackbarStatus.OPEN; _snackbarStatus(currentStatus); if (overlayEntries.isNotEmpty) overlayEntries.first.opaque = opaque; break;case AnimationStatus.forward:currentStatus = SnackbarStatus.OPENING; _snackbarStatus(currentStatus); break;case AnimationStatus.reverse:currentStatus = SnackbarStatus.CLOSING; _snackbarStatus(currentStatus); if (overlayEntries.isNotEmpty) overlayEntries.first.opaque = false; break;case AnimationStatus.dismissed:assert(!overlayEntries.first.opaque); currentStatus = SnackbarStatus.CLOSED; _snackbarStatus(currentStatus); if (!isCurrent) navigator.finalizeRoute(this); break;}changedInternalState();}@override void install() {assert(!_transitionCompleter.isCompleted, 'Cannot install a $runtimeType after disposing it.');_controller = createAnimationController();assert(_controller != null, '$runtimeType.createAnimationController() returned null.');_filterBlurAnimation = createBlurFilterAnimation();_filterColorAnimation = createColorFilterAnimation();_animation = createAnimation();assert(_animation != null, '$runtimeType.createAnimation() returned null.');super.install();}@override TickerFuture didPush() {super.didPush();assert(_controller != null, '$runtimeType.didPush called before calling install() or after calling dispose().');assert(!_transitionCompleter.isCompleted, 'Cannot reuse a $runtimeType after disposing it.');_animation.addStatusListener(_handleStatusChanged);_configureTimer();return _controller.forward();}@override void didReplace(Route<dynamic> oldRoute) {assert(_controller != null, '$runtimeType.didReplace called before calling install() or after calling dispose().');assert(!_transitionCompleter.isCompleted, 'Cannot reuse a $runtimeType after disposing it.');if (oldRoute is SnackRoute) _controller.value = oldRoute._controller.value;_animation.addStatusListener(_handleStatusChanged);super.didReplace(oldRoute);}@override bool didPop(T result) {assert(_controller != null, '$runtimeType.didPop called before calling install() or after calling dispose().');assert(!_transitionCompleter.isCompleted, 'Cannot reuse a $runtimeType after disposing it.');_result = result;_cancelTimer();if (_wasDismissedBySwipe) {Timer(Duration(milliseconds: 200), () => _controller.reset());_wasDismissedBySwipe = false;} else {_controller.reverse();}return super.didPop(result);}void _configureTimer() {if (snack.duration != null) {if (_timer != null && _timer.isActive) _timer.cancel();_timer = Timer(snack.duration, () {if (isCurrent) { navigator.pop(); } else if (isActive) { navigator.removeRoute(this); }});} else {_timer?.cancel();}}void _cancelTimer() {if (_timer != null && _timer.isActive) _timer.cancel();}bool canTransitionTo(SnackRoute<dynamic> nextRoute) => true;bool canTransitionFrom(SnackRoute<dynamic> previousRoute) => true;@override void dispose() {assert(!_transitionCompleter.isCompleted, 'Cannot dispose a $runtimeType twice.');_controller?.dispose();_transitionCompleter.complete(_result);super.dispose();}String get debugLabel => '$runtimeType';}class GetBar<T extends Object> extends StatefulWidget {GetBar({Key key, this.title, this.message, this.titleText, this.messageText, this.icon, this.shouldIconPulse = true, this.maxWidth, this.margin = const EdgeInsets.all(0.0), this.padding = const EdgeInsets.all(16), this.borderRadius = 0.0, this.borderColor, this.borderWidth = 1.0, this.backgroundColor = const Color(0xFF303030), this.leftBarIndicatorColor, this.boxShadows, this.backgroundGradient, this.mainButton, this.onTap, this.duration, this.isDismissible = true, this.dismissDirection = SnackDismissDirection.VERTICAL, this.showProgressIndicator = false, this.progressIndicatorController, this.progressIndicatorBackgroundColor, this.progressIndicatorValueColor, this.snackPosition = SnackPosition.BOTTOM, this.snackStyle = SnackStyle.FLOATING, this.forwardAnimationCurve = Curves.easeOutCirc, this.reverseAnimationCurve = Curves.easeOutCirc, this.animationDuration = const Duration(seconds: 1), this.barBlur = 0.0, this.overlayBlur = 0.0, this.overlayColor = Colors.transparent, this.userInputForm, SnackbarStatusCallback snackbarStatus}): snackbarStatus = (snackbarStatus ?? (status) {}), super(key: key);final SnackbarStatusCallback snackbarStatus;final String title, message;final Widget titleText, messageText, icon;final Color leftBarIndicatorColor, backgroundColor, borderColor, progressIndicatorBackgroundColor, overlayColor;final List<BoxShadow> boxShadows;final Gradient backgroundGradient;final bool shouldIconPulse, showProgressIndicator;final FlatButton mainButton;final OnTap onTap;final Duration duration, animationDuration;final AnimationController progressIndicatorController;final Animation<Color> progressIndicatorValueColor;final bool isDismissible;final double barBlur, overlayBlur, maxWidth, borderRadius, borderWidth;final EdgeInsets margin, padding;final SnackPosition snackPosition;final SnackDismissDirection dismissDirection;final SnackStyle snackStyle;final Curve forwardAnimationCurve, reverseAnimationCurve;final Form userInputForm;Future<T> show<T>() async => Get.showSnackbar(this);@override State createState() => _GetBarState<T>();}class _GetBarState<K extends Object> extends State<GetBar> with TickerProviderStateMixin {SnackbarStatus currentStatus;AnimationController _fadeController;Animation<double> _fadeAnimation;final Widget _emptyWidget = SizedBox(width: 0.0, height: 0.0);final double _initialOpacity = 1.0, _finalOpacity = 0.4;double _messageTopMargin;final Duration _pulseAnimationDuration = Duration(seconds: 1);bool _isTitlePresent;FocusScopeNode _focusNode;FocusAttachment _focusAttachment;@override void initState() {super.initState();assert(((widget.userInputForm != null || ((widget.message != null && widget.message.isNotEmpty) || widget.messageText != null))), """A message is mandatory if you are not using userInputForm. Set either a message or messageText""");_isTitlePresent = (widget.title != null || widget.titleText != null);_messageTopMargin = _isTitlePresent ? 6.0 : widget.padding.top;_configureLeftBarFuture();_configureProgressIndicatorAnimation();if (widget.icon != null && widget.shouldIconPulse) {_configurePulseAnimation(); _fadeController?.forward();}_focusNode = FocusScopeNode();_focusAttachment = _focusNode.attach(context);}@override void dispose() {_fadeController?.dispose();widget.progressIndicatorController?.removeListener(_progressListener);widget.progressIndicatorController?.dispose();_focusAttachment.detach();_focusNode.dispose();super.dispose();}final Completer<Size> _boxHeightCompleter = Completer<Size>();void _configureLeftBarFuture() {SchedulerBinding.instance.addPostFrameCallback((_) {final keyContext = backgroundBoxKey.currentContext;if (keyContext != null) {final box = keyContext.findRenderObject() as RenderBox; _boxHeightCompleter.complete(box.size);}});}void _configurePulseAnimation() {_fadeController = AnimationController(vsync: this, duration: _pulseAnimationDuration);_fadeAnimation = Tween(begin: _initialOpacity, end: _finalOpacity).animate(CurvedAnimation(parent: _fadeController, curve: Curves.linear));_fadeController.addStatusListener((status) {if (status == AnimationStatus.completed) _fadeController.reverse();if (status == AnimationStatus.dismissed) _fadeController.forward();});_fadeController.forward();}VoidCallback _progressListener;void _configureProgressIndicatorAnimation() {if (widget.showProgressIndicator && widget.progressIndicatorController != null) {_progressListener = () => setState(() {});widget.progressIndicatorController.addListener(_progressListener);_progressAnimation = CurvedAnimation(curve: Curves.linear, parent: widget.progressIndicatorController);}}@override Widget build(BuildContext context) => Align(heightFactor: 1.0, child: Material(color: widget.snackStyle == SnackStyle.FLOATING ? Colors.transparent : widget.backgroundColor, child: SafeArea(minimum: widget.snackPosition == SnackPosition.BOTTOM ? EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom) : EdgeInsets.only(top: MediaQuery.of(context).padding.top), bottom: widget.snackPosition == SnackPosition.BOTTOM, top: widget.snackPosition == SnackPosition.TOP, left: false, right: false, child: _getSnack())));Widget _getSnack() {Widget snack;if (widget.userInputForm != null) {snack = _generateInputSnack();} else {snack = _generateSnack();}return Stack(children: [FutureBuilder<Size>(future: _boxHeightCompleter.future, builder: (context, snapshot) { if (snapshot.hasData) return ClipRRect(borderRadius: BorderRadius.circular(widget.borderRadius), child: BackdropFilter(filter: ui.ImageFilter.blur(sigmaX: widget.barBlur, sigmaY: widget.barBlur), child: Container(height: snapshot.data.height, width: snapshot.data.width, decoration: BoxDecoration(color: Colors.transparent, borderRadius: BorderRadius.circular(widget.borderRadius))))); return _emptyWidget; }), snack]);}Widget _generateInputSnack() => Container(key: backgroundBoxKey, constraints: widget.maxWidth != null ? BoxConstraints(maxWidth: widget.maxWidth) : null, decoration: BoxDecoration(color: widget.backgroundColor, gradient: widget.backgroundGradient, boxShadow: widget.boxShadows, borderRadius: BorderRadius.circular(widget.borderRadius), border: widget.borderColor != null ? Border.all(color: widget.borderColor, width: widget.borderWidth) : null), child: Padding(padding: const EdgeInsets.only(left: 8.0, right: 8.0, bottom: 8.0, top: 16.0), child: FocusScope(child: widget.userInputForm, node: _focusNode, autofocus: true)));CurvedAnimation _progressAnimation;GlobalKey backgroundBoxKey = GlobalKey();Widget _generateSnack() => Container(key: backgroundBoxKey, constraints: widget.maxWidth != null ? BoxConstraints(maxWidth: widget.maxWidth) : null, decoration: BoxDecoration(color: widget.backgroundColor, gradient: widget.backgroundGradient, boxShadow: widget.boxShadows, borderRadius: BorderRadius.circular(widget.borderRadius), border: widget.borderColor != null ? Border.all(color: widget.borderColor, width: widget.borderWidth) : null), child: Column(mainAxisSize: MainAxisSize.min, children: [widget.showProgressIndicator ? LinearProgressIndicator(value: widget.progressIndicatorController != null ? _progressAnimation.value : null, backgroundColor: widget.progressIndicatorBackgroundColor, valueColor: widget.progressIndicatorValueColor) : _emptyWidget, Row(mainAxisSize: MainAxisSize.max, children: _getAppropriateRowLayout())]));List<Widget> _getAppropriateRowLayout() {double buttonRightPadding;var iconPadding = 0.0;if (widget.padding.right - 12 < 0) {buttonRightPadding = 4;} else {buttonRightPadding = widget.padding.right - 12;}if (widget.padding.left > 16.0) iconPadding = widget.padding.left;if (widget.icon == null && widget.mainButton == null) {return [_buildLeftBarIndicator(), Expanded(flex: 1, child: Column(crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisSize: MainAxisSize.min, children: <Widget>[(_isTitlePresent) ? Padding(padding: EdgeInsets.only(top: widget.padding.top, left: widget.padding.left, right: widget.padding.right), child: _getTitleText()) : _emptyWidget, Padding(padding: EdgeInsets.only(top: _messageTopMargin, left: widget.padding.left, right: widget.padding.right, bottom: widget.padding.bottom), child: widget.messageText ?? _getDefaultNotificationText())])),];} else if (widget.icon != null && widget.mainButton == null) {return <Widget>[_buildLeftBarIndicator(), ConstrainedBox(constraints: BoxConstraints.tightFor(width: 42.0 + iconPadding), child: _getIcon()), Expanded(flex: 1, child: Column(crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisSize: MainAxisSize.min, children: <Widget>[(_isTitlePresent) ? Padding(padding: EdgeInsets.only(top: widget.padding.top, left: 4.0, right: widget.padding.left), child: _getTitleText()) : _emptyWidget, Padding(padding: EdgeInsets.only(top: _messageTopMargin, left: 4.0, right: widget.padding.right, bottom: widget.padding.bottom), child: widget.messageText ?? _getDefaultNotificationText())]))];} else if (widget.icon == null && widget.mainButton != null) {return <Widget>[_buildLeftBarIndicator(), Expanded(flex: 1, child: Column(crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisSize: MainAxisSize.min, children: <Widget>[(_isTitlePresent) ? Padding(padding: EdgeInsets.only(top: widget.padding.top, left: widget.padding.left, right: widget.padding.right), child: _getTitleText()) : _emptyWidget, Padding(padding: EdgeInsets.only(top: _messageTopMargin, left: widget.padding.left, right: 8.0, bottom: widget.padding.bottom), child: widget.messageText ?? _getDefaultNotificationText())])), Padding(padding: EdgeInsets.only(right: buttonRightPadding), child: _getMainActionButton()),];} else {return <Widget>[_buildLeftBarIndicator(), ConstrainedBox(constraints: BoxConstraints.tightFor(width: 42.0 + iconPadding), child: _getIcon()), Expanded(flex: 1, child: Column(crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisSize: MainAxisSize.min, children: <Widget>[(_isTitlePresent) ? Padding(padding: EdgeInsets.only(top: widget.padding.top, left: 4.0, right: 8.0), child: _getTitleText()) : _emptyWidget, Padding(padding: EdgeInsets.only(top: _messageTopMargin, left: 4.0, right: 8.0, bottom: widget.padding.bottom), child: widget.messageText ?? _getDefaultNotificationText())])), Padding(padding: EdgeInsets.only(right: buttonRightPadding), child: _getMainActionButton()) ?? _emptyWidget,];}}Widget _buildLeftBarIndicator() {if (widget.leftBarIndicatorColor != null) {return FutureBuilder<Size>(future: _boxHeightCompleter.future, builder: (buildContext, snapshot) {if (snapshot.hasData) {return Container(color: widget.leftBarIndicatorColor, width: 5.0, height: snapshot.data.height);} else {return _emptyWidget;}});}return _emptyWidget;}Widget _getIcon() {if (widget.icon != null && widget.icon is Icon && widget.shouldIconPulse) return FadeTransition(opacity: _fadeAnimation, child: widget.icon);if (widget.icon != null) return widget.icon;return _emptyWidget;}Widget _getTitleText() => widget.titleText ?? Text(widget.title ?? "", style: TextStyle(fontSize: 16.0, color: Colors.white, fontWeight: FontWeight.bold));Text _getDefaultNotificationText() => Text(widget.message ?? "", style: TextStyle(fontSize: 14.0, color: Colors.white));FlatButton _getMainActionButton() => widget.mainButton;}class GetStream<T> {void Function() onListen, onPause, onResume;FutureOr<void> Function() onCancel;GetStream({this.onListen, this.onPause, this.onResume, this.onCancel});List<LightSubscription<T>> _onData = <LightSubscription<T>>[];bool _isBusy = false;FutureOr<bool> removeSubscription(LightSubscription<T> subs) async {if (!_isBusy) return _onData.remove(subs);await Future.delayed(Duration.zero);return _onData?.remove(subs);}FutureOr<void> addSubscription(LightSubscription<T> subs) async {if (!_isBusy) return _onData.add(subs);await Future.delayed(Duration.zero);return _onData.add(subs);}int get length => _onData?.length;bool get hasListeners => _onData.isNotEmpty;void _notifyData(T data) {_isBusy = true;for (final item in _onData) if (!item.isPaused) item._data?.call(data);_isBusy = false;}void _notifyError(Object error, [StackTrace stackTrace]) {assert(!isClosed, 'You cannot add errors to a closed stream.');_isBusy = true;var itemsToRemove = <LightSubscription<T>>[];for (final item in _onData) {if (!item.isPaused) {(stackTrace != null) ? item._onError?.call(error, stackTrace) : item._onError?.call(error); if (item.cancelOnError) { itemsToRemove.add(item); item.pause(); item._onDone?.call(); }}}for (final item in itemsToRemove) _onData.remove(item);_isBusy = false;}void _notifyDone() {assert(!isClosed, 'You cannot close a closed stream.');_isBusy = true;for (final item in _onData) if (!item.isPaused) item._onDone?.call();_isBusy = false;}T _value;T get value => _value;void add(T event) {assert(!isClosed, 'You cannot add event to closed Stream');_value = event;_notifyData(event);}bool get isClosed => _onData == null;void addError(Object error, [StackTrace stackTrace]) {assert(!isClosed, 'You cannot add error to closed Stream');_notifyError(error, stackTrace);}void close() {assert(!isClosed, 'You cannot close a closed Stream');_notifyDone();_onData = null;_isBusy = null;_value = null;}LightSubscription<T> listen(void Function(T event) onData, {Function onError, void Function() onDone, bool cancelOnError}) {final subs = LightSubscription<T>(removeSubscription, onPause: onPause, onResume: onResume, onCancel: onCancel)..onData(onData)..onError(onError)..onDone(onDone)..cancelOnError = cancelOnError;addSubscription(subs);onListen?.call();return subs;}Stream<T> get stream => GetStreamTransformation(addSubscription, removeSubscription);}class LightSubscription<T> extends StreamSubscription<T> {final RemoveSubscription<T> _removeSubscription;LightSubscription(this._removeSubscription, {this.onPause, this.onResume, this.onCancel});final void Function() onPause, onResume;final FutureOr<void> Function() onCancel;bool cancelOnError = false;@override Future<void> cancel() {_removeSubscription(this);onCancel?.call();return Future.value();}OnData<T> _data;Function _onError;Callback _onDone;bool _isPaused = false;@override void onData(OnData<T> handleData) => _data = handleData;@override void onError(Function handleError) => _onError = handleError;@override void onDone(Callback handleDone) => _onDone = handleDone;@override void pause([Future<void> resumeSignal]) {_isPaused = true;onPause?.call();}@override void resume() {_isPaused = false;onResume?.call();}@override bool get isPaused => _isPaused;@override Future<E> asFuture<E>([E futureValue]) => Future.value(futureValue);}class GetStreamTransformation<T> extends Stream<T> {final AddSubscription<T> _addSubscription;final RemoveSubscription<T> _removeSubscription;GetStreamTransformation(this._addSubscription, this._removeSubscription);@override LightSubscription<T> listen(void Function(T event) onData, {Function onError, void Function() onDone, bool cancelOnError}) {final subs = LightSubscription<T>(_removeSubscription)..onData(onData)..onError(onError)..onDone(onDone);_addSubscription(subs);return subs;}}class Node<T> {T data;Node<T> next;Node({this.data, this.next});}class MiniSubscription<T> {const MiniSubscription(this.data, this.onError, this.onDone, this.cancelOnError, this.listener);final OnData<T> data;final Function onError;final Callback onDone;final bool cancelOnError;Future<void> cancel() async => listener.removeListener(this);final FastList<T> listener;}class MiniStream<T> {FastList<T> listenable = FastList<T>();T _value;T get value => _value;set value(T val) => add(val);void add(T event) {assert(listenable != null);_value = event;listenable._notifyData(event);}void addError(Object error, [StackTrace stackTrace]) {assert(listenable != null);listenable._notifyError(error, stackTrace);}int get length => listenable.length;bool get hasListeners => listenable.isNotEmpty;bool get isClosed => listenable == null;MiniSubscription<T> listen(void Function(T event) onData, {Function onError, void Function() onDone, bool cancelOnError = false}) {final subs = MiniSubscription<T>(onData, onError, onDone, cancelOnError, listenable);listenable.addListener(subs);return subs;}void close() {if (listenable == null) throw 'You can not close a closed Stream';listenable._notifyDone();listenable = null;_value = null;}}class FastList<T> {Node<MiniSubscription<T>> _head;void _notifyData(T data) {var currentNode = _head;do {currentNode.data.data(data);currentNode = currentNode.next;} while (currentNode != null);}void _notifyDone() {var currentNode = _head;do {currentNode.data.onDone?.call();currentNode = currentNode.next;} while (currentNode != null);}void _notifyError(Object error, [StackTrace stackTrace]) {var currentNode = _head;while (currentNode != null) {currentNode.data.onError?.call(error, stackTrace);currentNode = currentNode.next;}}bool get isEmpty => _head == null;bool get isNotEmpty => !isEmpty;int get length {var length = 0;var currentNode = _head;while (currentNode != null) {currentNode = currentNode.next;length++;}return length;}MiniSubscription<T> _elementAt(int position) {if (isEmpty || length < position || position < 0) return null;var node = _head;var current = 0;while (current != position) {node = node.next;current++;}return node.data;}void addListener(MiniSubscription<T> data) {var newNode = Node(data: data);if (isEmpty) {_head = newNode;} else {var currentNode = _head;while (currentNode.next != null) currentNode = currentNode.next;currentNode.next = newNode;}}bool contains(T element) {var length = this.length;for (var i = 0; i < length; i++) {if (_elementAt(i) == element) return true;if (length != this.length) throw ConcurrentModificationError(this);}return false;}void removeListener(MiniSubscription<T> element) {var length = this.length;for (var i = 0; i < length; i++) {if (_elementAt(i) == element) {_removeAt(i);break;}}}MiniSubscription<T> _removeAt(int position) {var index = 0;var currentNode = _head;Node<MiniSubscription<T>> previousNode;if (isEmpty || length < position || position < 0) {throw Exception('Invalid position');} else if (position == 0) {_head = _head.next;} else {while (index != position) {previousNode = currentNode;currentNode = currentNode.next;index++;}(previousNode == null) ? _head = null : previousNode.next = currentNode.next;currentNode.next = null;} return currentNode.data;}}class RxNotifier<T> = RxInterface<T> with NotifyManager<T>;class RxBool extends _RxImpl<bool> {RxBool([bool initial]) : super(initial);bool get isTrue => value;bool get isFalse => !isTrue;bool operator &(bool other) => other && value;bool operator |(bool other) => other || value;bool operator ^(bool other) => !other == value;RxBool toggle() {subject.add(_value = !_value);return this;}@override String toString() => value ? "true" : "false";}class RxString extends _RxImpl<String> implements Comparable<String>, Pattern {RxString([String initial]) : super(initial);String operator +(String val) => _value + val;@override int compareTo(String other) => value.compareTo(other);bool endsWith(String other) => value.endsWith(other);bool startsWith(Pattern pattern, [int index = 0]) => value.startsWith(pattern, index);int indexOf(Pattern pattern, [int start = 0]) => value.indexOf(pattern, start);int lastIndexOf(Pattern pattern, [int start]) => value.lastIndexOf(pattern, start);bool get isEmpty => value.isEmpty;bool get isNotEmpty => !isEmpty;String substring(int startIndex, [int endIndex]) => value.substring(startIndex, endIndex);String trim() => value.trim();String trimLeft() => value.trimLeft();String trimRight() => value.trimRight();String padLeft(int width, [String padding = ' ']) => value.padLeft(width, padding);String padRight(int width, [String padding = ' ']) => value.padRight(width, padding);bool contains(Pattern other, [int startIndex = 0]) => value.contains(other, startIndex);String replaceAll(Pattern from, String replace) => value.replaceAll(from, replace);List<String> split(Pattern pattern) => value.split(pattern);List<int> get codeUnits => value.codeUnits;Runes get runes => value.runes;String toLowerCase() => value.toLowerCase();String toUpperCase() => value.toUpperCase();@override Iterable<Match> allMatches(String string, [int start = 0]) => value.allMatches(string, start);@override Match matchAsPrefix(String string, [int start = 0]) => value.matchAsPrefix(string, start);}class Rx<T> extends _RxImpl<T> { Rx([T initial]) : super(initial);@override dynamic toJson() {try {return (value as dynamic)?.toJson();} on Exception catch (_) {throw '$T has not method [toJson]';}}}class RxNum extends _BaseRxNum<num> {RxNum(num initial) : super(initial);num operator +(num other) {value += other;return value;}num operator -(num other) {value -= other;return value;}}class RxDouble extends _BaseRxNum<double> {RxDouble([double initial]) : super(initial);RxDouble operator +(num other) {value += other;return this;}RxDouble operator -(num other) {value -= other;return this;}@override double operator *(num other) => value * other;@override double operator %(num other) => value % other;@override double operator /(num other) => value / other;@override int operator ~/(num other) => value ~/ other;@override double operator -() => -value;@override double abs() => value.abs();@override double get sign => value.sign;@override int round() => value.round();@override int floor() => value.floor();@override int ceil() => value.ceil();@override int truncate() => value.truncate();@override double roundToDouble() => value.roundToDouble();@override double floorToDouble() => value.floorToDouble();@override double ceilToDouble() => value.ceilToDouble();@override double truncateToDouble() => value.truncateToDouble();}class RxInt extends _BaseRxNum<int> {RxInt([int initial]) : super(initial);RxInt operator +(int other) {value += other;return this;}RxInt operator -(int other) {value -= other;return this;}int operator &(int other) => value & other;int operator |(int other) => value | other;int operator ^(int other) => value ^ other;int operator ~() => ~value;int operator <<(int shiftAmount) => value << shiftAmount;int operator >>(int shiftAmount) => value >> shiftAmount;int modPow(int exponent, int modulus) => value.modPow(exponent, modulus);int modInverse(int modulus) => value.modInverse(modulus);int gcd(int other) => value.gcd(other);bool get isEven => value.isEven;bool get isOdd => value.isOdd;int get bitLength => value.bitLength;int toUnsigned(int width) => value.toUnsigned(width);int toSigned(int width) => value.toSigned(width);@override int operator -() => -value;@override int abs() => value.abs();@override int get sign => value.sign;@override int round() => value.round();@override int floor() => value.floor();@override int ceil() => value.ceil();@override int truncate() => value.truncate();@override double roundToDouble() => value.roundToDouble();@override double floorToDouble() => value.floorToDouble();@override double ceilToDouble() => value.ceilToDouble();@override double truncateToDouble() => value.truncateToDouble();}class RxList<E> extends ListMixin<E> with NotifyManager<List<E>>, RxObjectMixin<List<E>> implements RxInterface<List<E>> {RxList([List<E> initial = const []]) {if (initial != null) _value = List.from(initial);}factory RxList.filled(int length, E fill, {bool growable = false}) => RxList(List.filled(length, fill, growable: growable));factory RxList.empty({bool growable = false}) => RxList(List.empty(growable: growable));factory RxList.from(Iterable elements, {bool growable = true}) => RxList(List.from(elements, growable: growable));factory RxList.of(Iterable<E> elements, {bool growable = true}) => RxList(List.of(elements, growable: growable));factory RxList.generate(int length, E generator(int index), {bool growable = true}) => RxList(List.generate(length, generator, growable: growable));factory RxList.unmodifiable(Iterable elements) => RxList(List.unmodifiable(elements));@override Iterator<E> get iterator => value.iterator;@override void operator []=(int index, E val) {_value[index] = val;refresh();}@override RxList<E> operator +(Iterable<E> val) {addAll(val);refresh();return this;}@override E operator [](int index) => value[index];@override void add(E item) {_value.add(item);refresh();}@override void addAll(Iterable<E> item) {_value.addAll(item);refresh();}@override int get length => value.length;@override @protected List<E> get value {if (RxInterface.proxy != null) RxInterface.proxy.addListener(subject);return _value;}@override @protected @Deprecated('List.value is deprecated. use [yourList.assignAll(newList)]') set value(List<E> val) {if (_value == val) return;_value = val;refresh();}@override set length(int newLength) {_value.length = newLength;refresh();}@override void insertAll(int index, Iterable<E> iterable) {_value.insertAll(index, iterable);refresh();}@override Iterable<E> get reversed => value.reversed;@override Iterable<E> where(bool Function(E) test) => value.where(test);@override Iterable<T> whereType<T>() => value.whereType<T>();@override void sort([int compare(E a, E b)]) {_value.sort(compare);refresh();}}class RxMap<K, V> extends MapMixin<K, V> with NotifyManager<Map<K, V>>, RxObjectMixin<Map<K, V>> implements RxInterface<Map<K, V>> {RxMap([Map<K, V> initial = const {}]) {if (initial != null) _value = Map.from(initial);}factory RxMap.from(Map<K, V> other) => RxMap(Map.from(other));factory RxMap.of(Map<K, V> other) => RxMap(Map.of(other));factory RxMap.unmodifiable(Map<dynamic, dynamic> other) => RxMap(Map.unmodifiable(other));factory RxMap.identity() => RxMap(Map.identity());@override V operator [](Object key) => value[key];@override void operator []=(K key, V value) {_value[key] = value;refresh();}@override void clear() {_value.clear();refresh();}@override Iterable<K> get keys => value.keys;@override V remove(Object key) {final val = _value.remove(key);refresh();return val;}@override @protected Map<K, V> get value {if (RxInterface.proxy != null) RxInterface.proxy.addListener(subject);return _value;}@override @protected @Deprecated('Map.value is deprecated. use [yourMap.assignAll(newMap)]') set value(Map<K, V> val) {if (_value == val) return;_value = val;refresh();}}class RxSet<E> extends SetMixin<E> with NotifyManager<Set<E>>, RxObjectMixin<Set<E>> implements RxInterface<Set<E>> {RxSet([Set<E> initial = const {}]) {if (initial != null)_value = Set.from(initial);}RxSet<E> operator +(Set<E> val) {addAll(val);refresh();return this;}void update(void fn(Iterable<E> value)) {fn(value);refresh();}@override @protected Set<E> get value {if (RxInterface.proxy != null) RxInterface.proxy.addListener(subject);return _value;}@override @protected set value(Set<E> val) {if (_value == val) return;_value = val;refresh();}@override bool add(E value) {final val = _value.add(value);refresh();return val;}@override bool contains(Object element) => value.contains(element);@override Iterator<E> get iterator => value.iterator;@override int get length => value.length;@override E lookup(Object object) => value.lookup(object);@override bool remove(Object item) {var hasRemoved = _value.remove(item);if (hasRemoved) refresh();return hasRemoved;}@override Set<E> toSet() => value.toSet();@override void addAll(Iterable<E> item) {_value.addAll(item);refresh();}@override void clear() {_value.clear();refresh();}@override void removeAll(Iterable<Object> elements) {_value.removeAll(elements);refresh();}@override void retainAll(Iterable<Object> elements) {_value.retainAll(elements);refresh();}@override void retainWhere(bool Function(E) E) {_value.retainWhere(E);refresh();}}class Debouncer {final Duration delay;Timer _timer;Debouncer({this.delay});void call(void Function() action) {_timer?.cancel();_timer = Timer(delay, action);}bool get isRunning => _timer?.isActive ?? false;void cancel() => _timer?.cancel();}class Worker {Worker(this.worker, this.type);final Future<void> Function() worker;final String type;bool _disposed = false;bool get disposed => _disposed;void _log(String msg) => Get.log('$runtimeType $type $msg');void dispose() {if (_disposed) {_log('already disposed');return;}_disposed = true;worker();_log('disposed');}void call() => dispose();}class GetX<T extends DisposableInterface> extends StatefulWidget {final GetXControllerBuilder<T> builder;final bool autoRemove, global, assignId;final void Function(State state) initState, dispose, didChangeDependencies;final void Function(GetX oldWidget, State state) didUpdateWidget;final T init;final String tag;const GetX({this.tag, this.builder, this.global = true, this.autoRemove = true, this.initState, this.assignId = false, this.dispose, this.didChangeDependencies, this.didUpdateWidget, this.init});@override GetXState<T> createState() => GetXState<T>();}class GetXState<T extends DisposableInterface> extends State<GetX<T>> {GetXState() {_observer = RxNotifier();}RxInterface _observer;T controller;bool isCreator = false;StreamSubscription subs;@override void initState() {var isRegistered = GetInstance().isRegistered<T>(tag: widget.tag);if (widget.global) {if (isRegistered) {if (GetInstance().isPrepared<T>(tag: widget.tag)) {isCreator = true;} else {isCreator = false;}controller = GetInstance().find<T>(tag: widget.tag);} else {controller = widget.init;isCreator = true;GetInstance().put<T>(controller, tag: widget.tag);}} else {controller = widget.init;isCreator = true;controller?.onStart();}widget.initState?.call(this);if (widget.global && Get.smartManagement == SmartManagement.onlyBuilder) controller?.onStart();subs = _observer.listen((data) => setState(() {}));super.initState();}@override void didChangeDependencies() {super.didChangeDependencies();if (widget.didChangeDependencies != null) widget.didChangeDependencies(this);}@override void didUpdateWidget(GetX oldWidget) {super.didUpdateWidget(oldWidget as GetX<T>);if (widget.didUpdateWidget != null) widget.didUpdateWidget(oldWidget, this);}@override void dispose() {if (widget.dispose != null) widget.dispose(this);if (isCreator || widget.assignId) if (widget.autoRemove && GetInstance().isRegistered<T>(tag: widget.tag)) GetInstance().delete<T>(tag: widget.tag);subs.cancel();_observer.close();controller = null;isCreator = null;super.dispose();}Widget get notifyChildren {final observer = RxInterface.proxy;RxInterface.proxy = _observer;final result = widget.builder(controller);if (!_observer.canUpdate) {throw """\n[Get] the improper use of a GetX has been detected. \nYou should only use GetX or Obx for the specific widget that will be updated.\nIf you are seeing this error, you probably did not insert any observable variables into GetX/Obx \nor insert them outside the scope that GetX considers suitable for an update \n(example: GetX => HeavyWidget => variableObservable).\nIf you need to update a parent widget and a child widget, wrap each one in an Obx/GetX.""";}RxInterface.proxy = observer;return result;}@override Widget build(BuildContext context) => notifyChildren;}class Value<T> extends ListNotifier with StateMixin<T> implements ValueListenable<T> {Value(T val) {_value = val;_fillEmptyStatus();}@override T get value {notifyChildrens();return _value;}@override set value(T newValue) {if (_value == newValue) return;_value = newValue;refresh();}T call([T v]) {if (v != null) value = v;return value;}void update(void fn(T value)) {fn(value);refresh();}@override String toString() => value.toString();dynamic toJson() => (value as dynamic)?.toJson();}class RxStatus {final bool isEmpty, isSuccess, isError, isLoading;final String errorMessage;RxStatus._({this.isEmpty, this.isLoading, this.isError, this.isSuccess, this.errorMessage});factory RxStatus.loading() => RxStatus._(isLoading: true, isError: false, isSuccess: false, isEmpty: false);factory RxStatus.success() => RxStatus._(isLoading: false, isError: false, isSuccess: true, isEmpty: false);factory RxStatus.error([String message]) => RxStatus._(isLoading: false, isError: true, isSuccess: false, isEmpty: false, errorMessage: message);factory RxStatus.empty() => RxStatus._(isLoading: false, isError: false, isSuccess: false, isEmpty: true);}class _ObxState extends State<ObxWidget> {RxInterface _observer;StreamSubscription subs;_ObxState() {_observer = RxNotifier();}@override void initState() {subs = _observer.listen(_updateTree);super.initState();}void _updateTree(_) {if (mounted) setState(() {});}@override void dispose() {subs.cancel();_observer.close();super.dispose();}Widget get notifyChilds {final observer = RxInterface.proxy;RxInterface.proxy = _observer;final result = widget.build();if (!_observer.canUpdate) {throw """\n[Get] the improper use of a GetX has been detected. \nYou should only use GetX or Obx for the specific widget that will be updated.\nIf you are seeing this error, you probably did not insert any observable variables into GetX/Obx \nor insert them outside the scope that GetX considers suitable for an update \n(example: GetX => HeavyWidget => variableObservable).\nIf you need to update a parent widget and a child widget, wrap each one in an Obx/GetX.""";}RxInterface.proxy = observer;return result;}@override Widget build(BuildContext context) => notifyChilds;}class Obx extends ObxWidget {final WidgetCallback builder;const Obx(this.builder);@override Widget build() => builder();}class ObxValue<T extends RxInterface> extends ObxWidget {final Widget Function(T) builder; final T data; const ObxValue(this.builder, this.data, {Key key}) : super(key: key);@override Widget build() => builder(data);}class RxValue<T> extends ObxWidget {final Widget Function(T data) builder;final Rx<T> data = Rx<T>();RxValue(this.builder, {Key key}) : super(key: key);@override Widget build() => builder(data.value);}class GetResponsiveView<T> extends _GetResponsive<T> {final bool alwaysUseBuilder = true;GetResponsiveView({alwaysUseBuilder, ResponsiveScreenSettings settings = const ResponsiveScreenSettings(), Key key}) : super(settings, key: key);@override Widget build(BuildContext context) {screen.context = context;Widget widget;if (alwaysUseBuilder) {widget = builder();if (widget != null) return widget;}if (screen.isDesktop) {widget = desktop() ?? widget;if (widget != null) return widget;}if (screen.isTablet) {widget = tablet() ?? desktop();if (widget != null) return widget;}if (screen.isPhone) {widget = phone() ?? tablet() ?? desktop();if (widget != null) return widget;}return watch() ?? phone() ?? tablet() ?? desktop() ?? builder();}@override Widget builder() => null;@override Widget desktop() => null;@override Widget phone() => null;@override Widget tablet() => null;@override Widget watch() => null;}class ResponsiveScreenSettings {final double watchChangePoint, tabletChangePoint, desktopChangePoint;const ResponsiveScreenSettings({this.desktopChangePoint = 1200, this.tabletChangePoint = 600, this.watchChangePoint = 300});}class ResponsiveScreen {BuildContext context;final ResponsiveScreenSettings settings;bool _isPaltformDesktop;ResponsiveScreen(this.settings) {_isPaltformDesktop = GetPlatform.isDesktop;}double get height => context.height;double get width => context.width;bool get isDesktop => (screenType == ScreenType.Desktop);bool get isTablet => (screenType == ScreenType.Tablet);bool get isPhone => (screenType == ScreenType.Phone);bool get isWatch => (screenType == ScreenType.Watch);double get _getdeviceWidth {if (_isPaltformDesktop) return width;return context.mediaQueryShortestSide;}ScreenType get screenType {final deviceWidth = _getdeviceWidth;if (deviceWidth >= settings.desktopChangePoint) return ScreenType.Desktop;if (deviceWidth >= settings.tabletChangePoint) return ScreenType.Tablet;if (deviceWidth < settings.watchChangePoint) return ScreenType.Watch;return ScreenType.Phone;}T responsiveValue<T>({T mobile, T tablet, T desktop, T watch}) {if (isDesktop && desktop != null) return desktop;if (isTablet && tablet != null) return tablet;if (isPhone && mobile != null) return mobile;return watch;}}class _InheritedGetxController<T extends GetxController> extends InheritedWidget {final T model;final int version;_InheritedGetxController({Key key, @required Widget child, @required this.model}): version = model.notifierVersion, super(key: key, child: child);@override bool updateShouldNotify(_InheritedGetxController<T> oldWidget) => (oldWidget.version != version);}class GetBuilder<T extends GetxController> extends StatefulWidget {final GetControllerBuilder<T> builder;final bool global, assignId, autoRemove;final Object id;final String tag;final Object Function(T value) selector;final void Function(State state) initState, dispose, didChangeDependencies;final void Function(GetBuilder oldWidget, State state) didUpdateWidget;final T init;const GetBuilder({Key key, this.init, this.global = true, @required this.builder, this.autoRemove = true, this.assignId = false, this.initState, this.selector, this.tag, this.dispose, this.id, this.didChangeDependencies, this.didUpdateWidget}): assert(builder != null), super(key: key);static T of<T extends GetxController>(BuildContext context, {bool rebuild = false}) {var widget = rebuild ? context.dependOnInheritedWidgetOfExactType<_InheritedGetxController<T>>() : context.getElementForInheritedWidgetOfExactType<_InheritedGetxController<T>>()?.widget;if (widget == null) {throw 'Error: Could not find the correct dependency.';}return (widget as _InheritedGetxController<T>).model;}@override _GetBuilderState<T> createState() => _GetBuilderState<T>();}class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> with GetStateUpdaterMixin {T controller;bool isCreator = false;VoidCallback remove;Object _selector;List<VoidCallback> _watchs;static _GetBuilderState _currentState;void watch(VoidCallback listener) => (_watchs ??= <VoidCallback>[]).add(listener);@override void initState() {_GetBuilderState._currentState = this;super.initState();widget.initState?.call(this);var isRegistered = GetInstance().isRegistered<T>(tag: widget.tag);if (widget.global) {if (isRegistered) {isCreator = GetInstance().isPrepared<T>(tag: widget.tag); controller = GetInstance().find<T>(tag: widget.tag);} else {controller = widget.init; isCreator = true; GetInstance().put<T>(controller, tag: widget.tag);}} else {controller = widget.init;isCreator = true;controller?.onStart();}if (widget.selector != null) _selector = widget.selector(controller);_subscribeToController();}void _subscribeToController() {remove?.call();remove = (widget.id == null) ? controller?.addListener(_selector != null ? _selectorUpdate : getUpdate) : controller?.addListenerId(widget.id, _selector != null ? _selectorUpdate : getUpdate);}void _selectorUpdate() {var newSelector = widget.selector(controller);if (newSelector != _selector) {_selector = newSelector;getUpdate();}}@override void dispose() {super.dispose();widget.dispose?.call(this);if (isCreator || widget.assignId) if (widget.autoRemove && GetInstance().isRegistered<T>(tag: widget.tag)) GetInstance().delete<T>(tag: widget.tag);remove?.call();controller = null;isCreator = null;remove = null;_selector = null;_watchs = null;}@override void didChangeDependencies() {super.didChangeDependencies();widget.didChangeDependencies?.call(this);}@override void didUpdateWidget(GetBuilder oldWidget) {super.didUpdateWidget(oldWidget as GetBuilder<T>);if (oldWidget.id != widget.id) _subscribeToController();widget.didUpdateWidget?.call(oldWidget, this);}@override Widget build(BuildContext context) => _InheritedGetxController<T>(model: controller, child: widget.builder(controller));}class _GetCache<S extends GetLifeCycleBase> extends WidgetCache<GetWidget<S>> {S _controller;bool _isCreator = false;InstanceInfo info;@override void onInit() {info = GetInstance().getInstanceInfo<S>(tag: widget.tag);_isCreator = info.isPrepared && info.isCreate;if (info.isRegistered) _controller = Get.find<S>(tag: widget.tag);GetWidget._cache[widget] = _controller;super.onInit();}@override void onClose() {if (_isCreator) {Get.asap(() {widget.controller.onDelete();Get.log('"${widget.controller.runtimeType}" onClose() called');Get.log('"${widget.controller.runtimeType}" deleted from memory');GetWidget._cache[widget] = null;});}info = null;super.onClose();}@override Widget build(BuildContext context) => widget.build(context);}class GetWidgetCacheElement extends ComponentElement {GetWidgetCacheElement(GetWidgetCache widget): cache = widget.createWidgetCache(), super(widget) {cache._element = this;cache._widget = widget;}@override void mount(Element parent, dynamic newSlot) {cache?.onInit();super.mount(parent, newSlot);}@override Widget build() => cache.build(this);final WidgetCache<GetWidgetCache> cache;@override void performRebuild() => super.performRebuild();@override void activate() {super.activate();markNeedsBuild();}@override void unmount() {super.unmount();cache.onClose();cache._element = null;}}class ListNotifier implements Listenable {int _version = 0, _microtask = 0; int get notifierVersion => _version; int get notifierMicrotask => _microtask; List<GetStateUpdate> _updaters = <GetStateUpdate>[]; HashMap<Object, List<GetStateUpdate>> _updatersGroupIds = HashMap<Object, List<GetStateUpdate>>();@protected void refresh() {assert(_debugAssertNotDisposed());if (_microtask == _version) {_microtask++;scheduleMicrotask(() {_version++;_microtask = _version;_notifyUpdate();});}}void _notifyUpdate() {for (var element in _updaters) element();}void _notifyIdUpdate(Object id) {if (_updatersGroupIds.containsKey(id)) {final listGroup = _updatersGroupIds[id];for (var item in listGroup) item();}}@protected void refreshGroup(Object id) {assert(_debugAssertNotDisposed());if (_microtask == _version) {_microtask++;scheduleMicrotask(() {_version++;_microtask = _version;_notifyIdUpdate(id);});}}bool _debugAssertNotDisposed() {assert(() {if (_updaters == null) {throw FlutterError('''A $runtimeType was used after being disposed.\n'Once you have called dispose() on a $runtimeType, it can no longer be used.''');}return true;}());return true;}@protected void notifyChildrens() => TaskManager.instance.notify(_updaters);bool get hasListeners {assert(_debugAssertNotDisposed());return _updaters.isNotEmpty;}int get listeners {assert(_debugAssertNotDisposed());return _updaters.length;}@override void removeListener(VoidCallback listener) {assert(_debugAssertNotDisposed());_updaters.remove(listener);}void removeListenerId(Object id, VoidCallback listener) {assert(_debugAssertNotDisposed());if (_updatersGroupIds.containsKey(id)) _updatersGroupIds[id].remove(listener);_updaters.remove(listener);}@mustCallSuper void dispose() {assert(_debugAssertNotDisposed());_updaters = null;_updatersGroupIds = null;}@override Disposer addListener(GetStateUpdate listener) {assert(_debugAssertNotDisposed());_updaters.add(listener);return () => _updaters.remove(listener);}Disposer addListenerId(Object key, GetStateUpdate listener) {_updatersGroupIds[key] ??= <GetStateUpdate>[];_updatersGroupIds[key].add(listener);return () => _updatersGroupIds[key].remove(listener);}void disposeId(Object id) {_updatersGroupIds.remove(id);}}class TaskManager {TaskManager._();static TaskManager _instance;static TaskManager get instance => _instance ??= TaskManager._();GetStateUpdate _setter;List<VoidCallback> _remove;void notify(List<GetStateUpdate> _updaters) {if (_setter != null) {if (!_updaters.contains(_setter)) {_updaters.add(_setter);_remove.add(() => _updaters.remove(_setter));}}}Widget exchange(List<VoidCallback> disposers, GetStateUpdate setState, Widget Function(BuildContext) builder, BuildContext context) {_remove = disposers;_setter = setState;final result = builder(context);_remove = null;_setter = null;return result;}}class MixinBuilder<T extends GetxController> extends StatelessWidget {@required final Widget Function(T) builder;final bool autoRemove, global; final String id; final void Function(State state) initState, dispose, didChangeDependencies; final void Function(GetBuilder oldWidget, State state) didUpdateWidget; final T init;const MixinBuilder({Key key, this.init, this.global = true, this.builder, this.autoRemove = true, this.initState, this.dispose, this.id, this.didChangeDependencies, this.didUpdateWidget}): assert(builder != null), super(key: key);@override Widget build(BuildContext context) => GetBuilder<T>(init: init, global: global, autoRemove: autoRemove, initState: initState, dispose: dispose, id: id, didChangeDependencies: didChangeDependencies, didUpdateWidget: didUpdateWidget, builder: (controller) => Obx(() => builder.call(controller)));}class ValueBuilder<T> extends StatefulWidget {final T initialValue;final ValueBuilderBuilder<T> builder;final void Function() onDispose;final void Function(T) onUpdate;const ValueBuilder({Key key, this.initialValue, this.onDispose, this.onUpdate, @required this.builder}) : super(key: key);@override _ValueBuilderState<T> createState() => _ValueBuilderState<T>();}class _ValueBuilderState<T> extends State<ValueBuilder<T>> {T value;@override void initState() {super.initState();value = widget.initialValue;}@override Widget build(BuildContext context) => widget.builder(value, updater);void updater(T newValue) {widget.onUpdate?.call(newValue);setState(() {value = newValue;});}@override void dispose() {super.dispose();widget?.onDispose?.call();if (value is ChangeNotifier) {(value as ChangeNotifier)?.dispose();} else if (value is StreamController) {(value as StreamController)?.close();}value = null;}}class SimpleBuilder extends StatefulWidget {final Widget Function(BuildContext) builder;const SimpleBuilder({Key key, @required this.builder}): assert(builder != null), super(key: key);@override _SimpleBuilderState createState() => _SimpleBuilderState();}class _SimpleBuilderState extends State<SimpleBuilder> with GetStateUpdaterMixin {final disposers = <Disposer>[];@override void dispose() {super.dispose();for (final disposer in disposers) disposer();}@override Widget build(BuildContext context) => TaskManager.instance.exchange(disposers, getUpdate, widget.builder, context);}class _IntlHost {Locale locale, fallbackLocale;Map<String, Map<String, String>> translations = {};}class GetUtils {GetUtils._();static bool isNull(dynamic value) => value == null;static dynamic nil(dynamic s) => s == null ? null : s;static bool isNullOrBlank(dynamic value) {if (isNull(value)) return true;return _isEmpty(value);}static bool isBlank(dynamic value) => _isEmpty(value);static bool isNum(String value) {if (isNull(value)) return false;return num.tryParse(value) is num;}static bool isNumericOnly(String s) => hasMatch(s, r'^\d+$');static bool isAlphabetOnly(String s) => hasMatch(s, r'^[a-zA-Z]+$');static bool hasCapitalletter(String s) => hasMatch(s, r'[A-Z]');static bool isBool(String value) => isNull(value) ? false : (value == 'true' || value == 'false');static bool isVideo(String filePath) {var ext = filePath.toLowerCase();return ext.endsWith(".mp4") || ext.endsWith(".avi") || ext.endsWith(".wmv") || ext.endsWith(".rmvb") || ext.endsWith(".mpg") || ext.endsWith(".mpeg") || ext.endsWith(".3gp");}static bool isImage(String filePath) {final ext = filePath.toLowerCase();return ext.endsWith(".jpg") || ext.endsWith(".jpeg") || ext.endsWith(".png") || ext.endsWith(".gif") || ext.endsWith(".bmp");}static bool isAudio(String filePath) {final ext = filePath.toLowerCase();return ext.endsWith(".mp3") || ext.endsWith(".wav") || ext.endsWith(".wma") || ext.endsWith(".amr") || ext.endsWith(".ogg");}static bool isPPT(String filePath) {final ext = filePath.toLowerCase();return ext.endsWith(".ppt") || ext.endsWith(".pptx");}static bool isWord(String filePath) {final ext = filePath.toLowerCase();return ext.endsWith(".doc") || ext.endsWith(".docx");}static bool isExcel(String filePath) {final ext = filePath.toLowerCase();return ext.endsWith(".xls") || ext.endsWith(".xlsx");}static bool isAPK(String filePath) => filePath.toLowerCase().endsWith(".apk");static bool isPDF(String filePath) => filePath.toLowerCase().endsWith(".pdf");static bool isTxt(String filePath) => filePath.toLowerCase().endsWith(".txt");static bool isChm(String filePath) => filePath.toLowerCase().endsWith(".chm");static bool isVector(String filePath) => filePath.toLowerCase().endsWith(".svg");static bool isHTML(String filePath) => filePath.toLowerCase().endsWith(".html");static bool isUsername(String s) => hasMatch(s, r'^[a-zA-Z0-9][a-zA-Z0-9_.]+[a-zA-Z0-9]$');static bool isURL(String s) => hasMatch(s, r"^((((H|h)(T|t)|(F|f))(T|t)(P|p)((S|s)?))\://)?(www.|[a-zA-Z0-9].)[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,6}(\:[0-9]{1,5})*(/($|[a-zA-Z0-9\.\,\;\?\'\\\+&amp;%\$#\=~_\-]+))*$");static bool isEmail(String s) => hasMatch(s, r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$');static bool isPhoneNumber(String s) {if (s == null || s.length > 16 || s.length < 9) return false;return hasMatch(s, r'^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\s\./0-9]*$');}static bool isDateTime(String s) => hasMatch(s, r'^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}.\d{3}Z?$');static bool isMD5(String s) => hasMatch(s, r'^[a-f0-9]{32}$');static bool isSHA1(String s) => hasMatch(s, r'(([A-Fa-f0-9]{2}\:){19}[A-Fa-f0-9]{2}|[A-Fa-f0-9]{40})');static bool isSHA256(String s) => hasMatch(s, r'([A-Fa-f0-9]{2}\:){31}[A-Fa-f0-9]{2}|[A-Fa-f0-9]{64}');static bool isSSN(String s) => hasMatch(s, r'^(?!0{3}|6{3}|9[0-9]{2})[0-9]{3}-?(?!0{2})[0-9]{2}-?(?!0{4})[0-9]{4}$');static bool isBinary(String s) => hasMatch(s, r'^[0-1]+$');static bool isIPv4(String s) => hasMatch(s, r'^(?:(?:^|\.)(?:2(?:5[0-5]|[0-4]\d)|1?\d?\d)){4}$');static bool isIPv6(String s) => hasMatch(s, r'^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$');static bool isHexadecimal(String s) => hasMatch(s, r'^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$');static bool isPalindrom(String string) {final cleanString = string.toLowerCase().replaceAll(RegExp(r"\s+"), '').replaceAll(RegExp(r"[^0-9a-zA-Z]+"), "");for (var i = 0; i < cleanString.length; i++) if (cleanString[i] != cleanString[cleanString.length - i - 1]) return false;return true;}static bool isOneAKind(dynamic value) {if ((value is String || value is List) && !isNullOrBlank(value)) {final first = value[0];final len = value.length as num;for (var i = 0; i < len; i++) if (value[i] != first) return false;return true;}if (value is int) {final stringValue = value.toString();final first = stringValue[0];for (var i = 0; i < stringValue.length; i++) if (stringValue[i] != first) return false;return true;}return false;}static bool isPassport(String s) => hasMatch(s, r'^(?!^0+$)[a-zA-Z0-9]{6,9}$');static bool isCurrency(String s) => hasMatch(s, r'^(S?\$|\₩|Rp|\¥|\€|\₹|\₽|fr|R\$|R)?[ ]?[-]?([0-9]{1,3}[,.]([0-9]{3}[,.])*[0-9]{3}|[0-9]+)([,.][0-9]{1,2})?( ?(USD?|AUD|NZD|CAD|CHF|GBP|CNY|EUR|JPY|IDR|MXN|NOK|KRW|TRY|INR|RUB|BRL|ZAR|SGD|MYR))?$');static bool isLengthGreaterThan(dynamic value, int maxLength) {final length = _obtainDynamicLength(value);if (length == null) return false;return length > maxLength;}static bool isLengthGreaterOrEqual(dynamic value, int maxLength) {final length = _obtainDynamicLength(value);if (length == null) return false;return length >= maxLength;}@deprecated static bool isLengthLowerThan(dynamic value, int maxLength) => isLengthLessThan(value, maxLength);static bool isLengthLessThan(dynamic value, int maxLength) {final length = _obtainDynamicLength(value);if (length == null) return false;return length < maxLength;}@deprecated static bool isLengthLowerOrEqual(dynamic value, int maxLength) => isLengthLessOrEqual(value, maxLength);static bool isLengthLessOrEqual(dynamic value, int maxLength) {final length = _obtainDynamicLength(value);if (length == null) return false;return length <= maxLength;}static bool isLengthEqualTo(dynamic value, int otherLength) {final length = _obtainDynamicLength(value);if (length == null) return false;return length == otherLength;}static bool isLengthBetween(dynamic value, int minLength, int maxLength) => isNull(value) ? false : isLengthGreaterOrEqual(value, minLength) && isLengthLessOrEqual(value, maxLength);static bool isCaseInsensitiveContains(String a, String b) => a.toLowerCase().contains(b.toLowerCase());static bool isCaseInsensitiveContainsAny(String a, String b) {final lowA = a.toLowerCase();final lowB = b.toLowerCase();return lowA.contains(lowB) || lowB.contains(lowA);}static bool isLowerThan(num a, num b) => a < b;static bool isGreaterThan(num a, num b) => a > b;static bool isEqual(num a, num b) => a == b;static bool isCnpj(String cnpj) {if (cnpj == null) return false;final numbers = cnpj.replaceAll(RegExp(r'[^0-9]'), '');if (numbers.length != 14) return false;if (RegExp(r'^(\d)\1*$').hasMatch(numbers)) return false;final digits = numbers.split('').map(int.parse).toList();var calcDv1 = 0;var j = 0;for (var i in Iterable<int>.generate(12, (i) => i < 4 ? 5 - i : 13 - i)) calcDv1 += digits[j++] * i;calcDv1 %= 11;final dv1 = calcDv1 < 2 ? 0 : 11 - calcDv1;if (digits[12] != dv1) return false;var calcDv2 = 0;j = 0;for (var i in Iterable<int>.generate(13, (i) => i < 5 ? 6 - i : 14 - i)) calcDv2 += digits[j++] * i;calcDv2 %= 11;final dv2 = calcDv2 < 2 ? 0 : 11 - calcDv2;if (digits[13] != dv2) return false;return true;}static bool isCpf(String cpf) {if (cpf == null) return false;final numbers = cpf.replaceAll(RegExp(r'[^0-9]'), '');if (numbers.length != 11) return false;if (RegExp(r'^(\d)\1*$').hasMatch(numbers)) return false;final digits = numbers.split('').map(int.parse).toList();var calcDv1 = 0;for (var i in Iterable<int>.generate(9, (i) => 10 - i)) calcDv1 += digits[10 - i] * i;calcDv1 %= 11;final dv1 = calcDv1 < 2 ? 0 : 11 - calcDv1;if (digits[9] != dv1) return false;var calcDv2 = 0;for (var i in Iterable<int>.generate(10, (i) => 11 - i)) calcDv2 += digits[11 - i] * i;calcDv2 %= 11;final dv2 = calcDv2 < 2 ? 0 : 11 - calcDv2;if (digits[10] != dv2) return false;return true;}static String capitalize(String value) {if (isNull(value)) return null;if (isBlank(value)) return value;return value.split(' ').map(capitalizeFirst).join(' ');}static String capitalizeFirst(String s) {if (isNull(s)) return null;if (isBlank(s)) return s;return s[0].toUpperCase() + s.substring(1).toLowerCase();}static String removeAllWhitespace(String value) => value?.replaceAll(' ', '');static String camelCase(String value) {if (isNullOrBlank(value)) return null;final separatedWords = value.split(RegExp(r'[!@#<>?":`~;[\]\\|=+)(*&^%-\s_]+'));var newString = '';for (final word in separatedWords) newString += word[0].toUpperCase() + word.substring(1).toLowerCase();return newString[0].toLowerCase() + newString.substring(1);}static String numericOnly(String s, {bool firstWordOnly = false}) {var numericOnlyStr = '';for (var i = 0; i < s.length; i++) {if (isNumericOnly(s[i])) numericOnlyStr += s[i];if (firstWordOnly && numericOnlyStr.isNotEmpty && s[i] == " ") break;}return numericOnlyStr;}static bool hasMatch(String value, String pattern) => (value == null) ? false : RegExp(pattern).hasMatch(value);static void printFunction(String prefix, dynamic value, String info, {bool isError = false}) => Get.log('$prefix $value $info'.trim(), isError: isError);}class GetPlatform {static bool get isWeb => GeneralPlatform.isWeb;static bool get isMacOS => GeneralPlatform.isMacOS;static bool get isWindows => GeneralPlatform.isWindows;static bool get isLinux => GeneralPlatform.isLinux;static bool get isAndroid => GeneralPlatform.isAndroid;static bool get isIOS => GeneralPlatform.isIOS;static bool get isFuchsia => GeneralPlatform.isFuchsia;static bool get isMobile => GetPlatform.isIOS || GetPlatform.isAndroid;static bool get isDesktop => GetPlatform.isMacOS || GetPlatform.isWindows || GetPlatform.isLinux;}class GetMicrotask {int _version = 0, _microtask = 0;int get version => _version;int get microtask => _microtask;void exec(Function callback) {if (_microtask == _version) {_microtask++;scheduleMicrotask(() {_version++; _microtask = _version; callback();});}}}class GetQueue {final List<_Item> _queue = [];bool _active = false;void _check() async {if (!_active && _queue.isNotEmpty) {_active = true;var item = _queue.removeAt(0);try {item.completer.complete(await item.job());} on Exception catch (e) {item.completer.completeError(e);}_active = false;_check();}}Future<T> add<T>(Function job) {var completer = Completer<T>();_queue.add(_Item(completer, job));_check();return completer.future;}}class _Item {final dynamic completer;final dynamic job;_Item(this.completer, this.job);}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment