-
Notifications
You must be signed in to change notification settings - Fork 531
New sample: Configure Scene Environment #1758
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 4 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
cfd790e
new sample: Configure Scene Environment
praveenaak a0f3b54
update readme
praveenaak f8848fd
format xaml
praveenaak d21ebcd
run codemaid
praveenaak 269dc8d
Update src/MAUI/Maui.Samples/Samples/Scene/ConfigureSceneEnvironment/…
praveenaak 6c3fafe
Update src/MAUI/Maui.Samples/Samples/Scene/ConfigureSceneEnvironment/…
praveenaak 9c23ad6
Update src/MAUI/Maui.Samples/Samples/Scene/ConfigureSceneEnvironment/…
praveenaak b731e8c
Update src/MAUI/Maui.Samples/Samples/Scene/ConfigureSceneEnvironment/…
praveenaak aa44f9c
Update src/MAUI/Maui.Samples/Samples/Scene/ConfigureSceneEnvironment/…
praveenaak da8739c
Update src/MAUI/Maui.Samples/Samples/Scene/ConfigureSceneEnvironment/…
praveenaak f1c8340
Update src/MAUI/Maui.Samples/Samples/Scene/ConfigureSceneEnvironment/…
praveenaak 089f27c
code grouping and add comments
praveenaak dd320c8
Merge branch 'prav/configure-scene-environment' of https://github.com…
praveenaak 5fd1750
add comments
praveenaak File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
76 changes: 76 additions & 0 deletions
76
src/MAUI/Maui.Samples/Samples/Scene/ConfigureSceneEnvironment/ConfigureSceneEnvironment.xaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| <?xml version="1.0" encoding="utf-8" ?> | ||
| <ContentPage | ||
| x:Class="ArcGIS.Samples.ConfigureSceneEnvironment.ConfigureSceneEnvironment" | ||
| xmlns="http://schemas.microsoft.com/dotnet/2021/maui" | ||
| xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" | ||
| xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui"> | ||
| <Grid> | ||
| <esriUI:LocalSceneView x:Name="MySceneView" /> | ||
| <Border | ||
| Margin="10" | ||
| HorizontalOptions="{OnIdiom Phone=Fill, | ||
| Default=End}" | ||
| Style="{DynamicResource EsriSampleControlPanel}" | ||
| VerticalOptions="Start" | ||
| WidthRequest="{OnIdiom Phone=-1, | ||
| Default=300}"> | ||
| <ScrollView> | ||
| <StackLayout Padding="5" Spacing="5"> | ||
| <!-- Sky settings --> | ||
| <Label FontAttributes="Bold" Text="Sky" /> | ||
| <Grid | ||
| ColumnDefinitions="*,auto" | ||
| ColumnSpacing="10" | ||
| RowDefinitions="auto,auto"> | ||
| <Label Text="Stars" VerticalOptions="Center" /> | ||
| <Switch x:Name="StarsSwitch" Grid.Column="1" /> | ||
| <Label | ||
| Grid.Row="1" | ||
| Text="Atmosphere" | ||
| VerticalOptions="Center" /> | ||
| <Switch | ||
| x:Name="AtmosphereSwitch" | ||
| Grid.Row="1" | ||
| Grid.Column="1" /> | ||
| </Grid> | ||
| <BoxView HeightRequest="1" Color="Gray" /> | ||
|
|
||
| <!-- Background color settings --> | ||
| <Label FontAttributes="Bold" Text="Background color" /> | ||
| <Picker x:Name="BackgroundColorPicker" /> | ||
| <BoxView HeightRequest="1" Color="Gray" /> | ||
|
|
||
| <!-- Lighting settings --> | ||
| <Label FontAttributes="Bold" Text="Lighting" /> | ||
| <HorizontalStackLayout Spacing="10"> | ||
| <RadioButton | ||
| x:Name="SunRadioButton" | ||
| Content="Sun" | ||
| GroupName="LightingType" /> | ||
| <RadioButton | ||
| x:Name="VirtualRadioButton" | ||
| Content="Virtual" | ||
| GroupName="LightingType" /> | ||
| </HorizontalStackLayout> | ||
| <Grid ColumnDefinitions="*,auto" ColumnSpacing="10"> | ||
| <Label Text="Direct Shadows" VerticalOptions="Center" /> | ||
| <Switch x:Name="ShadowsSwitch" Grid.Column="1" /> | ||
| </Grid> | ||
| <Grid ColumnDefinitions="auto,*" ColumnSpacing="5"> | ||
| <Label | ||
| x:Name="HourLabel" | ||
| Grid.Column="0" | ||
| MinimumWidthRequest="75" | ||
| Text="Hour: 12:00" | ||
| VerticalTextAlignment="Center" /> | ||
| <Slider | ||
| x:Name="HourSlider" | ||
| Grid.Column="1" | ||
| Maximum="23" | ||
| Minimum="0" /> | ||
| </Grid> | ||
| </StackLayout> | ||
| </ScrollView> | ||
| </Border> | ||
| </Grid> | ||
| </ContentPage> | ||
219 changes: 219 additions & 0 deletions
219
...UI/Maui.Samples/Samples/Scene/ConfigureSceneEnvironment/ConfigureSceneEnvironment.xaml.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,219 @@ | ||
| // Copyright 2026 Esri. | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an | ||
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific | ||
| // language governing permissions and limitations under the License. | ||
|
|
||
| using Esri.ArcGISRuntime.Mapping; | ||
|
|
||
| namespace ArcGIS.Samples.ConfigureSceneEnvironment | ||
| { | ||
| [ArcGIS.Samples.Shared.Attributes.Sample( | ||
| name: "Configure scene environment", | ||
| category: "Scene", | ||
| description: "Configure the environment settings in a local scene to change the lighting conditions and background appearance.", | ||
| instructions: "At start-up, you will see a local scene with a set of scene environment controls. Adjusting the controls will change the scene's environment altering the presentation of the scene. Toggle the \"Stars\" and \"Atmosphere\" check boxes to enable or disable those features. Select a color from the dropdown to set a solid background color; selecting a new background color will disable the stars and atmosphere so you can see the new color. Switch between \"Sun\" and \"Virtual\" lighting, toggle \"Direct Shadows\", and adjust the hour slider to change the sun position.", | ||
| tags: new[] { "3D", "environment", "lighting", "scene" })] | ||
| public partial class ConfigureSceneEnvironment : ContentPage | ||
| { | ||
| // Background color options for the picker. | ||
| private readonly List<(string Name, System.Drawing.Color Color)> _backgroundColorOptions = new() | ||
| { | ||
| ("None", System.Drawing.Color.Transparent), | ||
| ("Black", System.Drawing.Color.Black), | ||
| ("Red", System.Drawing.Color.Red), | ||
| ("Orange", System.Drawing.Color.Orange), | ||
| ("Yellow", System.Drawing.Color.Yellow), | ||
| ("Green", System.Drawing.Color.Green), | ||
| ("Blue", System.Drawing.Color.Blue), | ||
| ("Purple", System.Drawing.Color.Purple), | ||
| ("White", System.Drawing.Color.White), | ||
| }; | ||
|
|
||
| // Track lighting date/time state. | ||
| private DateTimeOffset _lightingDateTime = new DateTimeOffset(2026, 3, 20, 12, 0, 0, TimeSpan.Zero); | ||
| private TimeSpan _lightingTimeZoneOffset = TimeSpan.Zero; | ||
| private int _lightingHour = 12; | ||
|
|
||
| public ConfigureSceneEnvironment() | ||
| { | ||
| InitializeComponent(); | ||
| _ = Initialize(); | ||
| } | ||
|
|
||
| private async Task Initialize() | ||
| { | ||
| try | ||
| { | ||
| // Populate the background color picker. | ||
| foreach (var colorOption in _backgroundColorOptions) | ||
| { | ||
| BackgroundColorPicker.Items.Add(colorOption.Name); | ||
| } | ||
|
|
||
| // Create and load the scene from an ArcGIS Online web scene. | ||
| var scene = new Scene(new Uri("https://www.arcgis.com/home/item.html?id=fcebd77958634ac3874bbc0e6b0677a4")); | ||
| await scene.LoadAsync(); | ||
|
|
||
| // Set the scene on the local scene view. | ||
| MySceneView.Scene = scene; | ||
|
|
||
| // Read initial environment state from the web scene. | ||
| var environment = scene.Environment; | ||
|
|
||
| // Set sky controls to match the scene. | ||
| AtmosphereSwitch.IsToggled = environment.IsAtmosphereEnabled; | ||
| StarsSwitch.IsToggled = environment.AreStarsEnabled; | ||
|
|
||
| // Set the background color control. | ||
| var bgColor = environment.BackgroundColor; | ||
| int colorIndex = _backgroundColorOptions.FindIndex(c => c.Color.ToArgb() == bgColor.ToArgb()); | ||
| BackgroundColorPicker.SelectedIndex = colorIndex >= 0 ? colorIndex : 0; | ||
|
|
||
| // Set lighting controls based on the scene's lighting. | ||
| if (environment.Lighting is SunLighting sunLighting) | ||
| { | ||
| SunRadioButton.IsChecked = true; | ||
| ShadowsSwitch.IsToggled = sunLighting.AreDirectShadowsEnabled; | ||
|
|
||
| // Record the simulated time from the web scene. | ||
| _lightingDateTime = sunLighting.SimulatedDate; | ||
|
|
||
| // Record the time zone offset if one was set on the web scene. | ||
| if (sunLighting.DisplayTimeZone != null) | ||
| { | ||
| _lightingTimeZoneOffset = sunLighting.DisplayTimeZone.Value; | ||
| } | ||
|
|
||
| // Record the localized hour from the web scene lighting. | ||
| _lightingHour = _lightingDateTime.Add(_lightingTimeZoneOffset).Hour; | ||
| HourSlider.Value = _lightingHour; | ||
| UpdateHourLabel(); | ||
|
|
||
| // Stars are available with sun lighting. | ||
| StarsSwitch.IsEnabled = true; | ||
| HourSlider.IsEnabled = true; | ||
| HourLabel.Opacity = 1; | ||
| HourSlider.Opacity = 1; | ||
| } | ||
|
praveenaak marked this conversation as resolved.
|
||
| else | ||
| { | ||
| VirtualRadioButton.IsChecked = true; | ||
| ShadowsSwitch.IsToggled = environment.Lighting.AreDirectShadowsEnabled; | ||
|
|
||
| // Stars and hour slider are not available with virtual lighting. | ||
| StarsSwitch.IsEnabled = false; | ||
| HourSlider.IsEnabled = false; | ||
| HourLabel.Opacity = 0.4; | ||
| HourSlider.Opacity = 0.4; | ||
| } | ||
|
praveenaak marked this conversation as resolved.
|
||
|
|
||
| // Wire up event handlers after initialization to avoid premature event handling. | ||
| StarsSwitch.Toggled += StarsSwitch_Toggled; | ||
| AtmosphereSwitch.Toggled += AtmosphereSwitch_Toggled; | ||
| BackgroundColorPicker.SelectedIndexChanged += BackgroundColorPicker_SelectedIndexChanged; | ||
| SunRadioButton.CheckedChanged += SunRadioButton_CheckedChanged; | ||
| VirtualRadioButton.CheckedChanged += VirtualRadioButton_CheckedChanged; | ||
| ShadowsSwitch.Toggled += ShadowsSwitch_Toggled; | ||
| HourSlider.ValueChanged += HourSlider_ValueChanged; | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| await Application.Current.Windows[0].Page.DisplayAlert("Error", ex.Message, "OK"); | ||
| } | ||
| } | ||
|
|
||
| private void StarsSwitch_Toggled(object sender, ToggledEventArgs e) | ||
| { | ||
| MySceneView.Scene.Environment.AreStarsEnabled = StarsSwitch.IsToggled; | ||
| } | ||
|
|
||
| private void AtmosphereSwitch_Toggled(object sender, ToggledEventArgs e) | ||
| { | ||
| MySceneView.Scene.Environment.IsAtmosphereEnabled = AtmosphereSwitch.IsToggled; | ||
| } | ||
|
|
||
| private void BackgroundColorPicker_SelectedIndexChanged(object sender, EventArgs e) | ||
| { | ||
| int index = BackgroundColorPicker.SelectedIndex; | ||
| if (index < 0 || index >= _backgroundColorOptions.Count) return; | ||
|
|
||
| var newColor = _backgroundColorOptions[index].Color; | ||
| MySceneView.Scene.Environment.BackgroundColor = newColor; | ||
|
|
||
| // Disable atmosphere and stars so the background color is visible. | ||
| MySceneView.Scene.Environment.IsAtmosphereEnabled = false; | ||
| AtmosphereSwitch.IsToggled = false; | ||
|
|
||
| MySceneView.Scene.Environment.AreStarsEnabled = false; | ||
| StarsSwitch.IsToggled = false; | ||
| } | ||
|
praveenaak marked this conversation as resolved.
|
||
|
|
||
| private void SunRadioButton_CheckedChanged(object sender, CheckedChangedEventArgs e) | ||
| { | ||
| if (!e.Value) return; | ||
|
|
||
| // Create a new SunLighting object preserving current state. | ||
| var sunLighting = new SunLighting(_lightingDateTime, ShadowsSwitch.IsToggled); | ||
|
|
||
| MySceneView.Scene.Environment.Lighting = sunLighting; | ||
|
praveenaak marked this conversation as resolved.
|
||
|
|
||
| // Enable stars and hour slider for sun lighting. | ||
| StarsSwitch.IsEnabled = true; | ||
| HourSlider.IsEnabled = true; | ||
| HourLabel.Opacity = 1; | ||
| HourSlider.Opacity = 1; | ||
|
|
||
| // Ensure the slider shows the correct hour. | ||
| _lightingHour = _lightingDateTime.Add(_lightingTimeZoneOffset).Hour; | ||
| HourSlider.Value = _lightingHour; | ||
| UpdateHourLabel(); | ||
| } | ||
|
|
||
| private void VirtualRadioButton_CheckedChanged(object sender, CheckedChangedEventArgs e) | ||
| { | ||
| if (!e.Value) return; | ||
|
|
||
| // Create a new VirtualLighting object preserving shadow state. | ||
| var virtualLighting = new VirtualLighting(ShadowsSwitch.IsToggled); | ||
|
|
||
| MySceneView.Scene.Environment.Lighting = virtualLighting; | ||
|
praveenaak marked this conversation as resolved.
|
||
|
|
||
| // Disable stars and hour slider for virtual lighting. | ||
| StarsSwitch.IsEnabled = false; | ||
| HourSlider.IsEnabled = false; | ||
| HourLabel.Opacity = 0.4; | ||
| HourSlider.Opacity = 0.4; | ||
| } | ||
|
|
||
| private void ShadowsSwitch_Toggled(object sender, ToggledEventArgs e) | ||
| { | ||
| MySceneView.Scene.Environment.Lighting.AreDirectShadowsEnabled = ShadowsSwitch.IsToggled; | ||
| } | ||
|
|
||
| private void HourSlider_ValueChanged(object sender, ValueChangedEventArgs e) | ||
| { | ||
| int newHour = (int)HourSlider.Value; | ||
| int hourDiff = newHour - _lightingHour; | ||
|
|
||
| _lightingHour = newHour; | ||
| UpdateHourLabel(); | ||
|
|
||
| // Update the time on the lighting object. | ||
| _lightingDateTime = _lightingDateTime.Add(TimeSpan.FromHours(hourDiff)); | ||
|
|
||
| if (MySceneView.Scene.Environment.Lighting is SunLighting sunLighting) | ||
| { | ||
| sunLighting.SimulatedDate = _lightingDateTime; | ||
| } | ||
| } | ||
|
praveenaak marked this conversation as resolved.
|
||
|
|
||
| private void UpdateHourLabel() | ||
| { | ||
| HourLabel.Text = $"Hour: {_lightingHour}:00"; | ||
| } | ||
| } | ||
| } | ||
Binary file added
BIN
+119 KB
...i.Samples/Samples/Scene/ConfigureSceneEnvironment/configuresceneenvironment.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
68 changes: 68 additions & 0 deletions
68
src/MAUI/Maui.Samples/Samples/Scene/ConfigureSceneEnvironment/readme.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| # Configure scene environment | ||
|
|
||
| Configure the environment settings in a local scene to change the lighting conditions and background appearance. | ||
|
|
||
|  | ||
|
|
||
| ## Use case | ||
|
|
||
| The scene environment defines the appearance of the local scene. This includes sky and background color settings, whether objects in the local scene cast shadows, and if virtual lighting or simulated sunlight is used to light the scene. | ||
|
|
||
| For an exploration scenario, like a city planning app, a developer might decide to enable sun lighting and direct shadows so the user can see how buildings and trees cast shadows at a given date and time. | ||
|
|
||
| For an analytic scenario, like examining a building scene layer, the developer may choose to use a virtual light source with shadows disabled and a solid background color instead of the atmosphere. | ||
|
|
||
| ## How to use the sample | ||
|
|
||
| At start-up, you will see a local scene with a set of scene environment controls at the bottom. Adjusting the controls will change the scene's environment altering the presentation of the scene. | ||
|
|
||
| ### Sky and Background color settings | ||
|
|
||
| Toggling the "Stars" and "Atmosphere" buttons will enable or disable those features. | ||
|
|
||
| Selecting a color from the dropdown will set a solid color for the background color. Selecting a new background color will disable the stars and atmosphere so you can see the new color. | ||
|
|
||
| Some notes about the behavior of the sky and background: | ||
|
|
||
| * The atmosphere is rendered in front of the stars and the stars are rendered in front of the background color. | ||
| * Stars are not rendered when using virtual lighting. | ||
| * To fully see the background color, atmosphere and stars must be deactivated. | ||
| * The background color shows in the night sky if the atmosphere is enabled and the stars are disabled. | ||
|
|
||
| ### Lighting settings | ||
|
|
||
| The lighting buttons switch between sun lighting and virtual lighting. Switching to virtual lighting disables the "Stars" button since stars do not exist in a virtually lit scene. The time slider is also disabled under virtual lighting since time does not have an effect on the virtual light. | ||
|
|
||
| The "Direct Shadows" button will enable or disable the rendering of shadows for 3d objects in the scene. Shadows are not rendered for surface terrain. | ||
|
|
||
| If sun lighting is active, the slider under the buttons will set the hour of the day ranging from midnight to 11pm (23:00). Dragging the bar will change the position of the simulated sun causing changes to shading and direct shadows. | ||
|
|
||
| ## How it works | ||
|
|
||
| 1. Create a `Scene` from an online resource and add it to the `LocalSceneView`. The sample's controls are updated to reflect the web scene's initial environment. | ||
| 2. Changes to the sky and background color settings will set values directly on the `SceneEnvironment` object. | ||
| * `IsAtmosphereEnabled` and `AreStarsEnabled` are boolean properties dictating whether the atmosphere and star field are visible. | ||
| * Colors selected from the dropdown are set to the `BackgroundColor`. | ||
| 3. Changes to the settings in the lighting controls manipulate the `SceneLighting` object in the `SceneEnvironment.Lighting` property. | ||
| * Switching between "Sun" and "Virtual" lighting assigns a new `SunLighting` or `VirtualLighting` object to the lighting property. | ||
| * Sun lighting simulates the position of the sun based on a given date and time. This includes lighting conditions for day, twilight, and night. | ||
| * For virtual lighting, the light source is always on and is slightly offset from the camera. As the scene rotated or panned, the light source stays in the same position relative to the camera. | ||
| * The "Direct Shadows" button sets the `AreDirectShadowsEnabled` boolean property on the lighting object. This toggles the shadows cast by objects in the scene. | ||
| * If `SunLighting` is active, manipulating the slider changes the hour of the `SimulatedDate` property on the lighting object. `VirtualLighting` does not have a slider because the lighting is always the same regardless of time. | ||
|
|
||
| ## Relevant API | ||
|
|
||
| * LocalSceneView | ||
| * Scene | ||
| * SceneEnvironment | ||
| * SceneLighting | ||
| * SunLighting | ||
| * VirtualLighting | ||
|
|
||
| ## About the data | ||
|
|
||
| The [WebM Open 3D Esri Local Scene](https://www.arcgis.com/home/item.html?id=fcebd77958634ac3874bbc0e6b0677a4) used for this sample contains a clipped local scene consisting of a surface and 3D objects representing the buildings. The scene is located in Santa Fe, New Mexico, USA. | ||
|
|
||
| ## Tags | ||
|
|
||
| 3D, environment, lighting, scene |
30 changes: 30 additions & 0 deletions
30
src/MAUI/Maui.Samples/Samples/Scene/ConfigureSceneEnvironment/readme.metadata.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| { | ||
| "category": "Scene", | ||
| "description": "Configure the environment settings in a local scene to change the lighting conditions and background appearance.", | ||
| "formal_name": "ConfigureSceneEnvironment", | ||
| "ignore": false, | ||
| "images": [ | ||
| "configuresceneenvironment.jpg" | ||
| ], | ||
| "keywords": [ | ||
| "3D", | ||
| "environment", | ||
| "lighting", | ||
| "scene" | ||
| ], | ||
| "offline_data": [], | ||
| "redirect_from": [], | ||
| "relevant_apis": [ | ||
| "LocalSceneView", | ||
| "Scene", | ||
| "SceneEnvironment", | ||
| "SceneLighting", | ||
| "SunLighting", | ||
| "VirtualLighting" | ||
| ], | ||
| "snippets": [ | ||
| "ConfigureSceneEnvironment.xaml.cs", | ||
| "ConfigureSceneEnvironment.xaml" | ||
| ], | ||
| "title": "Configure scene environment" | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.