protected override void Dispose(bool disposing) { if (_disposed) { return; } _disposed = true; if (disposing) { if (_currentFragment != null && !FragmentManager.IsDestroyed) { FragmentTransaction transaction = FragmentManager.BeginTransactionEx(); transaction.RemoveEx(_currentFragment); transaction.SetTransitionEx((int)FragmentTransit.None); transaction.CommitAllowingStateLossEx(); FragmentManager.ExecutePendingTransactionsEx(); _currentFragment = null; } _parent = null; _pageContainer = null; _fragmentManager = null; RemoveAllViews(); DisposeChildRenderers(); } base.Dispose(disposing); }
protected virtual void OnBeforeFragmentChanging(FragmentTransaction ft, Fragment fragment, MvxFragmentPresentationAttribute attribute, MvxViewModelRequest request) { if (CurrentActivity is IMvxAndroidSharedElements sharedElementsActivity) { var elements = new List<string>(); foreach (KeyValuePair<string, View> item in sharedElementsActivity.FetchSharedElementsToAnimate(attribute, request)) { var transitionName = item.Value.GetTransitionNameSupport(); if (!string.IsNullOrEmpty(transitionName)) { ft.AddSharedElement(item.Value, transitionName); elements.Add($"{item.Key}:{transitionName}"); } else { MvxLog.Instance.Warn("A XML transitionName is required in order to transition a control when navigating."); } } if (elements.Count > 0) fragment.Arguments.PutString(SharedElementsBundleKey, string.Join("|", elements)); } if (!attribute.EnterAnimation.Equals(int.MinValue) && !attribute.ExitAnimation.Equals(int.MinValue)) { if (!attribute.PopEnterAnimation.Equals(int.MinValue) && !attribute.PopExitAnimation.Equals(int.MinValue)) ft.SetCustomAnimations(attribute.EnterAnimation, attribute.ExitAnimation, attribute.PopEnterAnimation, attribute.PopExitAnimation); else ft.SetCustomAnimations(attribute.EnterAnimation, attribute.ExitAnimation); } if (attribute.TransitionStyle != int.MinValue) ft.SetTransitionStyle(attribute.TransitionStyle); }
public void OnTabUnselected(AndroidX.AppCompat.App.ActionBar.Tab tab, AndroidX.Fragment.App.FragmentTransaction ft) { if (fragment != null) { ft.Detach(fragment); } }
void AddTransitionTimer(TaskCompletionSource <bool> tcs, Fragment fragment, FragmentManager fragmentManager, IReadOnlyCollection <Fragment> fragmentsToRemove, int duration, bool shouldUpdateToolbar) { Device.StartTimer(TimeSpan.FromMilliseconds(duration), () => { tcs.TrySetResult(true); Current?.SendAppearing(); if (shouldUpdateToolbar) { UpdateToolbar(); } if (fragmentsToRemove.Count > 0) { FragmentTransaction fragmentTransaction = fragmentManager.BeginTransactionEx(); foreach (Fragment frag in fragmentsToRemove) { fragmentTransaction.RemoveEx(frag); } fragmentTransaction.CommitAllowingStateLossEx(); } return(false); }); }
protected override void SetupPageTransition(AndroidX.Fragment.App.FragmentTransaction transaction, bool isPush) { switch (_transitionType) { case TransitionType.None: return; case TransitionType.Default: return; case TransitionType.Fade: if (isPush) { transaction.SetCustomAnimations(Resource.Animation.enter_right, Resource.Animation.exit_left, Resource.Animation.enter_left, Resource.Animation.exit_right); } else { transaction.SetCustomAnimations(Resource.Animation.enter_left, Resource.Animation.exit_right, Resource.Animation.enter_right, Resource.Animation.exit_left); } break; default: return; } }
void RemovePage(Page page) { if (!_isAttachedToWindow) { PushCurrentPages(); } Fragment fragment = GetPageFragment(page); if (fragment == null) { return; } #if DEBUG // Enables logging of moveToState operations to logcat #pragma warning disable CS0618 // Type or member is obsolete FragmentManager.EnableDebugLogging(true); #pragma warning restore CS0618 // Type or member is obsolete #endif // Go ahead and take care of the fragment bookkeeping for the page being removed FragmentTransaction transaction = FragmentManager.BeginTransactionEx(); transaction.RemoveEx(fragment); transaction.CommitAllowingStateLossEx(); // And remove the fragment from our own stack _fragmentStack.Remove(fragment); Device.StartTimer(TimeSpan.FromMilliseconds(10), () => { UpdateToolbar(); return(false); }); }
protected virtual void OnBeforeFragmentChanging( FragmentTransaction fragmentTransaction, Fragment fragment, MvxFragmentPresentationAttribute attribute, MvxViewModelRequest request) { if (fragmentTransaction == null) { throw new ArgumentNullException(nameof(fragmentTransaction)); } if (fragment == null) { throw new ArgumentNullException(nameof(fragment)); } ValidateArguments(attribute, request); if (CurrentActivity.IsActivityAlive() && CurrentActivity is IMvxAndroidSharedElements sharedElementsActivity) { var elements = new List <string>(); foreach (var(key, value) in sharedElementsActivity.FetchSharedElementsToAnimate(attribute, request)) { var transitionName = value.GetTransitionNameSupport(); if (!string.IsNullOrEmpty(transitionName)) { fragmentTransaction.AddSharedElement(value, transitionName); elements.Add($"{key}:{transitionName}"); } else { _logger.Value?.Log(LogLevel.Warning, "A XML transitionName is required in order to transition a control when navigating."); } } if (elements.Count > 0) { fragment.Arguments.PutString(SharedElementsBundleKey, string.Join("|", elements)); } } if (!attribute.EnterAnimation.Equals(int.MinValue) && !attribute.ExitAnimation.Equals(int.MinValue)) { if (!attribute.PopEnterAnimation.Equals(int.MinValue) && !attribute.PopExitAnimation.Equals(int.MinValue)) { fragmentTransaction.SetCustomAnimations(attribute.EnterAnimation, attribute.ExitAnimation, attribute.PopEnterAnimation, attribute.PopExitAnimation); } else { fragmentTransaction.SetCustomAnimations(attribute.EnterAnimation, attribute.ExitAnimation); } } if (attribute.TransitionStyle != int.MinValue) { fragmentTransaction.SetTransitionStyle(attribute.TransitionStyle); } }
private void LoadAllFragments() { AndroidX.Fragment.App.FragmentTransaction transaction = SupportFragmentManager.BeginTransaction(); transaction.Add(Resource.Id.WidgetPlaceholder, CreateFragment("clock_fragment"), "clock_fragment"); transaction.Add(Resource.Id.WidgetPlaceholder, CreateFragment("notification_fragment"), "notification_fragment"); transaction.Add(Resource.Id.WidgetPlaceholder, CreateFragment("music_fragment"), "music_fragment"); transaction.Commit(); }
private void ShowFareDialog(double fare) { var collectPaymentFragment = new CollectPaymentFragment(newRideDetails, fare); collectPaymentFragment.Cancelable = false; AndroidX.Fragment.App.FragmentTransaction ft = SupportFragmentManager.BeginTransaction(); ft.Add(collectPaymentFragment, "collect_pay_frag"); ft.CommitAllowingStateLoss(); }
void ExecuteTransaction(FragmentTransaction transaction) { // We don't currently support fragment restoration // So we don't need to worry about loss of this fragment's state transaction.CommitAllowingStateLossEx(); // The transaction need to be executed after View has been attached // So Fragment Manager can find the View being added FragmentManager.ExecutePendingTransactionsEx(); }
private void DisplayPic(int rotation) { picDisplayFragment = new PicDisplayFragment(bitmap, rotation); picDisplayFragment.Cancelable = true; AndroidX.Fragment.App.FragmentTransaction ft = ChildFragmentManager.BeginTransaction(); ft.Add(picDisplayFragment, "pic_display"); ft.CommitAllowingStateLoss(); picDisplayFragment.SavePic += PicDisplayFragment_SavePic; picDisplayFragment.RetakePic += PicDisplayFragment_RetakePic; }
protected virtual void SetupPageTransition(FragmentTransaction transaction, bool isPush) { if (isPush) { transaction.SetTransitionEx((int)FragmentTransit.FragmentOpen); } else { transaction.SetTransitionEx((int)FragmentTransit.FragmentClose); } }
protected override void SetupPageTransition(FragmentTransaction transaction, bool isPush) { if (isPush) { transaction.SetCustomAnimations(Resource.Animation.enter_from_right, Resource.Animation.exit_to_left); } else { transaction.SetCustomAnimations(Resource.Animation.enter_from_left, Resource.Animation.exit_to_right); } }
private void MainNavigationView_NavigationItemSelected(object sender, NavigationView.NavigationItemSelectedEventArgs e) { try { string title = ""; ft = SupportFragmentManager.BeginTransaction(); switch (e.MenuItem.ItemId) { case Resource.Id.CalcNavigation_ExpItem: ft.Replace(Resource.Id.CalcFragmentContainer, expItemCalcF, "ExpItemCalc"); title = Resources.GetString(Resource.String.TitleName_ExpItemCalc); break; case Resource.Id.CalcNavigation_Core: ft.Replace(Resource.Id.CalcFragmentContainer, coreCalcF, "CoreCalc"); title = Resources.GetString(Resource.String.TitleName_CoreCalc); break; case Resource.Id.CalcNavigation_CoalitionGrade: ft.Replace(Resource.Id.CalcFragmentContainer, coalitionGradeF, "CoalitionGradeCalc"); title = Resources.GetString(Resource.String.TitleName_CoalitionGrade); break; case Resource.Id.CalcNavigation_SkillTraining: ft.Replace(Resource.Id.CalcFragmentContainer, skillTrainingCalcF, "SkillTraining"); title = Resources.GetString(Resource.String.TitleName_SkillTrainingCalc); break; case Resource.Id.CalcNavigation_FSTGradeUp: ft.Replace(Resource.Id.CalcFragmentContainer, fstGradeUpF, "FSTGradeUp"); title = Resources.GetString(Resource.String.TitleName_FSTGradeUpCalc); break; case Resource.Id.CalcNavigation_AreaExp: ft.Replace(Resource.Id.CalcFragmentContainer, areaExpCalcF, "AreaExpCalc"); title = Resources.GetString(Resource.String.TitleName_AreaExpCalc); break; } ft.Commit(); mainDrawerLayout.CloseDrawer(GravityCompat.Start); SupportActionBar.Title = title; } catch (Exception ex) { ETC.LogError(ex, this); Toast.MakeText(this, Resource.String.ChangeMode_Error, ToastLength.Short).Show(); } }
protected override void SetupPageTransition(AndroidX.Fragment.App.FragmentTransaction transaction, bool isPush) { if (isPush) { transaction.SetCustomAnimations(Resource.Animator.enter_right, Resource.Animator.exit_left, Resource.Animator.enter_left, Resource.Animator.exit_right); } else { transaction.SetCustomAnimations(Resource.Animator.enter_left, Resource.Animator.exit_right, Resource.Animator.enter_right, Resource.Animator.exit_left); } }
protected override void OnAttachedToWindow() { base.OnAttachedToWindow(); if (_transaction == null) { return; } ExecuteTransaction(_transaction); _transaction = null; }
public static void ShowNoNetDialog(bool val) { if (val != true) { noNetBottomSheet = new NoNetBottomSheet(_context); noNetBottomSheet.Cancelable = false; AndroidX.Fragment.App.FragmentTransaction ft = _context.SupportFragmentManager.BeginTransaction(); ft.Add(noNetBottomSheet, "no_net"); ft.CommitAllowingStateLoss(); } else { return; } }
public static FragmentTransaction ReplaceContentAnimated(this FragmentTransaction source, Fragment fragment, string tag = null) { source.AddToBackStack(null); source.SetCustomAnimations(Resource.Animation.enter_from_right, Resource.Animation.exit_to_left, Resource.Animation.enter_from_left, Resource.Animation.exit_to_right); if (tag == null) { source.Replace(Resource.Id.content_display_frame, fragment); } else { source.Replace(Resource.Id.content_display_frame, fragment, tag); } return(source); }
protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); if (ETC.useLightTheme) { SetTheme(Resource.Style.GFS_NoActionBar_Light); } // Create your application here SetContentView(Resource.Layout.CalcMainLayout); ETC.LoadDBSync(ETC.skillTrainingList, "SkillTraining.gfs", true); ETC.LoadDBSync(ETC.freeOPList, "FreeOP.gfs", true); // Set Main Drawer mainDrawerLayout = FindViewById <DrawerLayout>(Resource.Id.Calc_MainDrawerLayout); mainDrawerLayout.DrawerOpened += delegate { SupportActionBar.SetHomeAsUpIndicator(Resource.Drawable.MenuOpen); }; mainDrawerLayout.DrawerClosed += delegate { SupportActionBar.SetHomeAsUpIndicator(Resource.Drawable.Menu); }; mainNavigationView = FindViewById <NavigationView>(Resource.Id.Calc_NavigationView); mainNavigationView.NavigationItemSelected += MainNavigationView_NavigationItemSelected; // Set ActionBar SetSupportActionBar(FindViewById <AndroidX.AppCompat.Widget.Toolbar>(Resource.Id.Calc_Toolbar)); SupportActionBar.SetDisplayHomeAsUpEnabled(true); SupportActionBar.SetDisplayShowTitleEnabled(true); SupportActionBar.SetHomeButtonEnabled(true); SupportActionBar.Title = Resources.GetString(Resource.String.TitleName_ExpItemCalc); SupportActionBar.SetHomeAsUpIndicator(Resource.Drawable.Menu); // Set Fragment ft = SupportFragmentManager.BeginTransaction(); expItemCalcF = new ExpItemCalc(); coreCalcF = new DummyCore(); coalitionGradeF = new CoalitionGrade(); skillTrainingCalcF = new SkillTraining(); fstGradeUpF = new FSTGradeUp(); areaExpCalcF = new AreaExpCalc(); ft.Add(Resource.Id.CalcFragmentContainer, expItemCalcF, "ExpItemCalc"); ft.Commit(); }
public void OnTabSelected(AndroidX.AppCompat.App.ActionBar.Tab tab, AndroidX.Fragment.App.FragmentTransaction ft) { var className = Java.Lang.Class.FromType(fragmentType).Name; if (fragment == null) { fragment = AndroidX.Fragment.App.Fragment.Instantiate(parent, className, args); ft.Add(Android.Resource.Id.Content, fragment, tag); } else { ft.Attach(fragment); } // TODO: Add AutoTracking here once the autoTracking fixes make it into the SDK. }
public void Initialize() { LatLng southwest = new LatLng(30, 118); CameraPosition.Builder builder = new CameraPosition.Builder(); CameraPosition cameraPosition = builder.Target(southwest).Zoom(2).Bearing(2.0f).Tilt(2.5f).Build(); HuaweiMapOptions huaweiMapOptions = new HuaweiMapOptions().InvokeCamera(cameraPosition); mSupportMapFragment = SupportMapFragment.NewInstance(huaweiMapOptions); mSupportMapFragment.GetMapAsync(this); AndroidX.Fragment.App.FragmentManager fragmentManager = SupportFragmentManager; AndroidX.Fragment.App.FragmentTransaction fragmentTransaction = fragmentManager.BeginTransaction(); fragmentTransaction.Add(Resource.Id.frame_supportmapcode, mSupportMapFragment); fragmentTransaction.Commit(); }
public void ShowFragment0() { try { if (FragmentListTab0.Count < 0) { return; } // If user presses it while still on that tab it removes all fragments from the list if (FragmentListTab0.Count > 1) { FragmentTransaction ft = Context.SupportFragmentManager.BeginTransaction(); for (var index = FragmentListTab0.Count - 1; index > 0; index--) { var oldFragment = FragmentListTab0[index]; if (FragmentListTab0.Contains(oldFragment)) { FragmentListTab0.Remove(oldFragment); } if (oldFragment.IsAdded) { ft.Remove(oldFragment); } HideFragmentFromList(FragmentListTab0, ft); } var currentFragment = FragmentListTab0[FragmentListTab0.Count - 1]; ft.Show(currentFragment).Commit(); } else { var currentFragment = FragmentListTab0[FragmentListTab0.Count - 1]; if (currentFragment != null) { DisplayFragment(currentFragment); } } } catch (Exception e) { Methods.DisplayReportResultTrack(e); } }
protected override void OnCreate(Bundle savedInstanceState) { try { //ETC.BasicInitializeApp(this); base.OnCreate(savedInstanceState); if (ETC.useLightTheme) { SetTheme(Resource.Style.GFS_NoActionBar_Light); } // Create your application here SetContentView(Resource.Layout.ShortGuideBookMainLayout); snackbarLayout = FindViewById <CoordinatorLayout>(Resource.Id.ShortGuideBookSnackbarLayout); mainDrawerLayout = FindViewById <DrawerLayout>(Resource.Id.ShortGuideBookMainDrawerLayout); mainDrawerLayout.DrawerOpened += delegate { SupportActionBar.SetHomeAsUpIndicator(Resource.Drawable.MenuOpen); }; mainDrawerLayout.DrawerClosed += delegate { SupportActionBar.SetHomeAsUpIndicator(Resource.Drawable.Menu); }; SetSupportActionBar(FindViewById <AndroidX.AppCompat.Widget.Toolbar>(Resource.Id.ShortGuideBookMainToolbar)); SupportActionBar.SetDisplayHomeAsUpEnabled(true); SupportActionBar.SetDisplayShowTitleEnabled(true); SupportActionBar.SetHomeButtonEnabled(true); SupportActionBar.SetHomeAsUpIndicator(Resource.Drawable.Menu); drawerListView = FindViewById <ListView>(Resource.Id.ShortGuideBookImageListView); drawerListView.ItemClick += DrawerListView_ItemClick; ShortGuideBookF = new ShortGuideBookScreen(); ft = SupportFragmentManager.BeginTransaction(); ft.Add(Resource.Id.ShortGuideBookContainer, ShortGuideBookF, "ShortGuideBookScreen"); ft.Commit(); InitList(); } catch (Exception ex) { ETC.LogError(ex, this); Toast.MakeText(this, Resource.String.Activity_OnCreateError, ToastLength.Short).Show(); } }
protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); ETC.SetDialogTheme(); if (ETC.useLightTheme) { SetTheme(Resource.Style.GFS_Toolbar_Light); } // Create your application here SetContentView(Resource.Layout.CartoonMainLayout); // Find View & Connect Event toolbarCartoonTitle = FindViewById <TextView>(Resource.Id.CartoonToolbarCartoonTitle); mainDrawerLayout = FindViewById <DrawerLayout>(Resource.Id.CartoonMainDrawerLayout); mainDrawerLayout.DrawerOpened += delegate { SupportActionBar.SetHomeAsUpIndicator(Resource.Drawable.MenuOpen); }; mainDrawerLayout.DrawerClosed += delegate { SupportActionBar.SetHomeAsUpIndicator(Resource.Drawable.Menu); }; drawerListView = FindViewById <ListView>(Resource.Id.CartoonMainNavigationListView); drawerListView.ItemClick += DrawerListView_ItemClick; // Set ActionBar SetSupportActionBar(FindViewById <AndroidX.AppCompat.Widget.Toolbar>(Resource.Id.CartoonMainToolbar)); SupportActionBar.SetDisplayHomeAsUpEnabled(true); SupportActionBar.SetDisplayShowTitleEnabled(true); SupportActionBar.SetHomeButtonEnabled(true); SupportActionBar.SetHomeAsUpIndicator(Resource.Drawable.Menu); // Set Fragment cartoonScreenF = new CartoonScreen(); ft = SupportFragmentManager.BeginTransaction(); ft.Add(Resource.Id.CartoonContainer, cartoonScreenF, "CartoonScreen"); ft.Commit(); LoadCategoryList(); }
private void BeginCameraInvoke(CaptureType captureType) { switch (captureType) { case CaptureType.ProfilePic: BeforeUSnapFragment bUSnap = new BeforeUSnapFragment(); AndroidX.Fragment.App.FragmentTransaction ft = ChildFragmentManager.BeginTransaction(); ft.Add(bUSnap, "camera_intro"); ft.CommitAllowingStateLoss(); bUSnap.StartCameraAsync += CameraIntroDialog_StartCameraAsync; break; case CaptureType.FrontOfLicense: break; case CaptureType.BackOfLicense: break; } }
public void DisplayFragment(Fragment newFragment) { try { FragmentTransaction ft = Context.SupportFragmentManager.BeginTransaction(); HideFragmentFromList(FragmentListTab0, ft); HideFragmentFromList(FragmentListTab1, ft); if (PageNumber == 0) { if (!FragmentListTab0.Contains(newFragment)) { FragmentListTab0.Add(newFragment); } } if (PageNumber == 1) { if (!FragmentListTab1.Contains(newFragment)) { FragmentListTab1.Add(newFragment); } } if (!newFragment.IsAdded) { ft.Add(Resource.Id.mainFragment, newFragment, PageNumber + newFragment.Id.ToString()); } else { ft.Show(newFragment); } ft.CommitNow(); Context.SupportFragmentManager.ExecutePendingTransactions(); } catch (Exception e) { Methods.DisplayReportResultTrack(e); } }
public static void HideFragmentFromList(List <Fragment> fragmentList, FragmentTransaction ft) { try { if (fragmentList.Count > 0) { foreach (var fra in fragmentList) { if (fra.IsAdded && fra.IsVisible) { ft.Hide(fra); } } } } catch (Exception e) { Methods.DisplayReportResultTrack(e); } }
public void RemoveFragment(Fragment oldFragment) { FragmentTransaction ft = Context.SupportFragmentManager.BeginTransaction(); if (PageNumber == 0) { if (FragmentListTab0.Contains(oldFragment)) { FragmentListTab0.Remove(oldFragment); } } if (PageNumber == 1) { if (FragmentListTab1.Contains(oldFragment)) { FragmentListTab1.Remove(oldFragment); } } HideFragmentFromList(FragmentListTab0, ft); HideFragmentFromList(FragmentListTab1, ft); if (oldFragment.IsAdded) { ft.Remove(oldFragment); } if (PageNumber == 0) { var currentFragment = FragmentListTab0[FragmentListTab0.Count - 1]; ft.Show(currentFragment).Commit(); } else if (PageNumber == 1) { var currentFragment = FragmentListTab1[FragmentListTab1.Count - 1]; ft.Show(currentFragment).Commit(); } }
protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); if (ETC.useLightTheme) { SetTheme(Resource.Style.GFS_Toolbar_Light); } // Create your application here SetContentView(Resource.Layout.GFOSTPlayer); if (MusicRepo.ostPlayer == null) { MusicRepo.ostPlayer = CrossSimpleAudioPlayer.Current; } mainDrawerLayout = FindViewById <DrawerLayout>(Resource.Id.GFOSTPlayerMainDrawerLayout); mainDrawerLayout.DrawerOpened += delegate { SupportActionBar.SetHomeAsUpIndicator(Resource.Drawable.MenuOpen); }; mainDrawerLayout.DrawerClosed += delegate { SupportActionBar.SetHomeAsUpIndicator(Resource.Drawable.Menu); }; drawerListView = FindViewById <ListView>(Resource.Id.GFOSTPlayerNavigationListView); drawerListView.ItemClick += DrawerListView_ItemSelected; SetSupportActionBar(FindViewById <AndroidX.AppCompat.Widget.Toolbar>(Resource.Id.GFOSTPlayerToolbar)); SupportActionBar.SetDisplayHomeAsUpEnabled(true); SupportActionBar.SetDisplayShowTitleEnabled(true); SupportActionBar.SetHomeButtonEnabled(true); SupportActionBar.SetHomeAsUpIndicator(Resource.Drawable.Menu); gfOSTPlayerScreenF = new GFOSTPlayerScreen(); ft = SupportFragmentManager.BeginTransaction(); ft.Add(Resource.Id.GFOSTPlayerMainLayout, gfOSTPlayerScreenF, "GFOSTPlayerScreen"); ft.Commit(); LoadCategoryList(); }
void AddTransitionTimer(TaskCompletionSource <bool> tcs, Fragment fragment, FragmentManager fragmentManager, IReadOnlyCollection <Fragment> fragmentsToRemove, int duration, bool shouldUpdateToolbar) { PostDelayed(() => { tcs.TrySetResult(true); Current?.SendAppearing(); if (shouldUpdateToolbar) { UpdateToolbar(); } if (fragmentsToRemove.Count > 0) { FragmentTransaction fragmentTransaction = fragmentManager.BeginTransactionEx(); foreach (Fragment frag in fragmentsToRemove) { fragmentTransaction.RemoveEx(frag); } fragmentTransaction.CommitAllowingStateLossEx(); } }, duration); }