Skip to content
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

Stat Analysis Implementation #6

Draft
wants to merge 39 commits into
base: feature/anlstat
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
8064939
update parm/config/gfs
kevindougherty-noaa Aug 20, 2024
8772e61
Fixed test on UNAVAILBLE in python Rocoto check (#2842)
TerrenceMcGuinness-NOAA Aug 20, 2024
659bcbe
Convert staging job to python and yaml (#2651)
KateFriedman-NOAA Aug 20, 2024
1b18f2f
support ATM forecast only on Azure (#2827)
weihuang-jedi Aug 20, 2024
2ce2116
Add snow DA update and recentering for the EnKF forecasts (#2690)
CoryMartin-NOAA Aug 23, 2024
ea22a73
Update omega calculation (#2751)
XiaqiongZhou-NOAA Aug 23, 2024
1231c9a
Add GEFS C48 support on AWS (#2818)
weihuang-jedi Aug 26, 2024
7a724e0
Support ATM forecast only on Google (#2832)
weihuang-jedi Aug 26, 2024
935ac64
Fix gdas build on Gaea and add Gaea to available CI list (#2857)
AnilKumar-NOAA Aug 27, 2024
9ad7d3e
Add JEDI ATM lgetkf observer and solver jobs (#2833)
RussTreadon-NOAA Aug 28, 2024
85c7659
Support coupling on AWS (#2859)
weihuang-jedi Aug 28, 2024
5ccdd8b
Correct ocean `MOM.res_#` stage copy (#2868)
KateFriedman-NOAA Aug 29, 2024
7f160f6
Add diffusion/diag B for aerosol DA and some other needed changes (#2…
CoryMartin-NOAA Aug 29, 2024
66fc89c
Add 3 and 9 hr increment files to IC staging (#2876)
AndrewEichmann-NOAA Aug 30, 2024
5c304b5
Support global-workflow GEFS C48 on Google Cloud (#2861)
weihuang-jedi Sep 4, 2024
2e4f4b7
Add ability to run CI test C96_atm3DVar.yaml to Gaea-C5 (#2885)
DavidBurrows-NCO Sep 4, 2024
e4f0733
first pass at stat analyis python script. Copying aerostat file
kevindougherty-noaa Sep 5, 2024
d412762
add exglobal stat analysis script
kevindougherty-noaa Sep 5, 2024
17dbc15
update scripts
kevindougherty-noaa Sep 5, 2024
b621034
pycodestyle
kevindougherty-noaa Sep 5, 2024
d3ea8e2
Update aerosol climatology to 2013-2024 mean (#2888)
AnningCheng-NOAA Sep 6, 2024
6519211
Eliminate race conditions and remove DATAROOT last in cleanup (#2893)
DavidHuber-NOAA Sep 6, 2024
ac93a9b
Reenable Orion Cycling Support (#2877)
DavidHuber-NOAA Sep 7, 2024
2816c3b
Add an archive task to GEFS system to archive files locally (#2816)
AntonMFernando-NOAA Sep 7, 2024
b8080cd
Restructure the bufr sounding job (#2853)
BoCui-NOAA Sep 7, 2024
49f697a
Create JEDI class (#2805)
DavidNew-NOAA Sep 7, 2024
243e1e0
add anlstat config file
kevindougherty-noaa Sep 9, 2024
587a7c5
add global stats job
kevindougherty-noaa Sep 9, 2024
0953c0f
Add FAQ page and a caution with using reserved variables (#2898)
aerorahul Sep 9, 2024
4d0b219
add symlink from gdasapp to parm file
kevindougherty-noaa Sep 9, 2024
b443915
Consolidate python configuration dictionaries (#2839)
DavidHuber-NOAA Sep 10, 2024
c7e5f05
revert sorc symlink addition due to changes in GDASApp
kevindougherty-noaa Sep 10, 2024
668c39d
remove extra config file
kevindougherty-noaa Sep 10, 2024
7893aa1
remove DATA line
kevindougherty-noaa Sep 10, 2024
6ea681b
Replace APRUN with APRUN_default (#2871)
DavidHuber-NOAA Sep 11, 2024
108db4d
Add new UPP links to .gitignore (#2904)
DavidHuber-NOAA Sep 12, 2024
2b98b84
merge develop
kevindougherty-noaa Sep 12, 2024
9cd2fcd
Revert "remove DATA line"
kevindougherty-noaa Sep 12, 2024
e15422d
Merge branch 'feature/anlstat' into feature/anlstat-kd
CoryMartin-NOAA Sep 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 5 additions & 39 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,8 @@ parm/gdas/soca
parm/gdas/jcb-gdas
parm/gdas/jcb-algorithms
parm/monitor
parm/post/AEROSOL_LUTS.dat
parm/post/nam_micro_lookup.dat
parm/post/optics_luts_DUST.dat
parm/post/gtg.config.gfs
parm/post/gtg_imprintings.txt
parm/post/optics_luts_DUST_nasa.dat
parm/post/optics_luts_NITR_nasa.dat
parm/post/optics_luts_SALT.dat
Expand All @@ -70,51 +67,19 @@ parm/post/optics_luts_WASO.dat
parm/post/optics_luts_WASO_nasa.dat
parm/post/params_grib2_tbl_new
parm/post/post_tag_gfs128
parm/post/post_tag_gfs65
parm/post/postcntrl_gefs.xml
parm/post/postcntrl_gefs_aerosol.xml
parm/post/postcntrl_gefs_anl.xml
parm/post/postcntrl_gefs_chem.xml
parm/post/postcntrl_gefs_f00.xml
parm/post/postcntrl_gfs.xml
parm/post/postcntrl_gfs_anl.xml
parm/post/postcntrl_gfs_f00.xml
parm/post/postcntrl_gfs_f00_two.xml
parm/post/postcntrl_gfs_flux.xml
parm/post/postcntrl_gfs_flux_f00.xml
parm/post/postcntrl_gfs_goes.xml
parm/post/postcntrl_gfs_goes.xml-new
parm/post/postcntrl_gfs_two.xml
parm/post/postcntrl_gfs_wafs.xml
parm/post/postcntrl_gfs_wafs_anl.xml
parm/post/postxconfig-NT-GEFS-ANL.txt
parm/post/postxconfig-NT-GEFS-F00.txt
parm/post/postxconfig-NT-GEFS-F00-aerosol.txt
parm/post/postxconfig-NT-GEFS-WAFS.txt
parm/post/postxconfig-NT-GEFS-aerosol.txt
parm/post/postxconfig-NT-GEFS.txt
parm/post/postxconfig-NT-GFS-ANL.txt
parm/post/postxconfig-NT-GFS-F00-TWO.txt
parm/post/postxconfig-NT-GFS-F00.txt
parm/post/postxconfig-NT-GFS-FLUX-F00.txt
parm/post/postxconfig-NT-GFS-FLUX.txt
parm/post/postxconfig-NT-GFS-GOES.txt
parm/post/postxconfig-NT-GFS-TWO.txt
parm/post/postxconfig-NT-GFS-WAFS-ANL.txt
parm/post/postxconfig-NT-GFS-WAFS.txt
parm/post/postxconfig-NT-GFS.txt
parm/post/postxconfig-NT-gefs-aerosol.txt
parm/post/postxconfig-NT-gefs-chem.txt
parm/post/gfs
parm/post/gefs
parm/post/ocean.csv
parm/post/ice.csv
parm/post/ocnicepost.nml.jinja2
parm/ufs/noahmptable.tbl
parm/ufs/model_configure.IN
parm/ufs/model_configure_nest.IN
parm/ufs/input_global_nest.nml.IN
parm/ufs/MOM_input_*.IN
parm/ufs/MOM6_data_table.IN
parm/ufs/ice_in.IN
parm/ufs/ufs.configure.*.IN
parm/ufs/post_itag_gfs
parm/wafs

# Ignore sorc and logs folders from externals
Expand Down Expand Up @@ -200,6 +165,7 @@ ush/month_name.sh
ush/imsfv3_scf2ioda.py
ush/atparse.bash
ush/run_bufr2ioda.py
ush/bufr2ioda_insitu*

# version files
versions/build.ver
Expand Down
6 changes: 3 additions & 3 deletions ci/Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ pipeline {
Machine = machine[0].toUpperCase() + machine.substring(1)
echo "Getting Common Workspace for ${Machine}"
ws("${custom_workspace[machine]}/${env.CHANGE_ID}") {
properties([parameters([[$class: 'NodeParameterDefinition', allowedSlaves: ['built-in', 'Hercules-EMC', 'Hera-EMC', 'Orion-EMC'], defaultSlaves: ['built-in'], name: '', nodeEligibility: [$class: 'AllNodeEligibility'], triggerIfResult: 'allCases']])])
properties([parameters([[$class: 'NodeParameterDefinition', allowedSlaves: ['built-in', 'Hercules-EMC', 'Hera-EMC', 'Orion-EMC', 'Gaea'], defaultSlaves: ['built-in'], name: '', nodeEligibility: [$class: 'AllNodeEligibility'], triggerIfResult: 'allCases']])])
GH = sh(script: "which gh || echo '~/bin/gh'", returnStdout: true).trim()
CUSTOM_WORKSPACE = "${WORKSPACE}"
sh(script: "mkdir -p ${CUSTOM_WORKSPACE}/RUNTESTS;rm -Rf ${CUSTOM_WORKSPACE}/RUNTESTS/*")
Expand Down Expand Up @@ -267,7 +267,7 @@ pipeline {
}
}
}


stage( '5. FINALIZE' ) {
agent { label NodeName[machine].toLowerCase() }
Expand Down Expand Up @@ -297,6 +297,6 @@ pipeline {
}
}
}
}
}
}
}
2 changes: 1 addition & 1 deletion ci/cases/pr/C48mx500_3DVarAOWCDA.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ arguments:
resdetocean: 5.0
comroot: {{ 'RUNTESTS' | getenv }}/COMROOT
expdir: {{ 'RUNTESTS' | getenv }}/EXPDIR
icsdir: {{ 'ICSDIR_ROOT' | getenv }}/C48mx500
icsdir: {{ 'ICSDIR_ROOT' | getenv }}/C48mx500/20240610
idate: 2021032412
edate: 2021032418
nens: 0
Expand Down
2 changes: 1 addition & 1 deletion ci/cases/pr/C96C48_hybatmDA.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ arguments:
resensatmos: 48
comroot: {{ 'RUNTESTS' | getenv }}/COMROOT
expdir: {{ 'RUNTESTS' | getenv }}/EXPDIR
icsdir: {{ 'ICSDIR_ROOT' | getenv }}/C96C48
icsdir: {{ 'ICSDIR_ROOT' | getenv }}/C96C48/20240610
idate: 2021122018
edate: 2021122106
nens: 2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ arguments:
pslot: {{ 'pslot' | getenv }}
app: ATMA
resdetatmos: 96
resensatmos: 48
comroot: {{ 'RUNTESTS' | getenv }}/COMROOT
expdir: {{ 'RUNTESTS' | getenv }}/EXPDIR
icsdir: {{ 'ICSDIR_ROOT' | getenv }}/C96C48
icsdir: {{ 'ICSDIR_ROOT' | getenv }}/C96C48/20240610
idate: 2021122012
edate: 2021122100
nens: 0
nens: 2
gfs_cyc: 1
start: cold
yaml: {{ HOMEgfs }}/ci/cases/yamls/atmaerosnowDA_defaults_ci.yaml
Expand Down
3 changes: 1 addition & 2 deletions ci/cases/pr/C96C48_ufs_hybatmDA.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ arguments:
resensatmos: 48
comroot: {{ 'RUNTESTS' | getenv }}/COMROOT
expdir: {{ 'RUNTESTS' | getenv }}/EXPDIR
icsdir: {{ 'ICSDIR_ROOT' | getenv }}/C96C48
icsdir: {{ 'ICSDIR_ROOT' | getenv }}/C96C48/20240610
idate: 2024022318
edate: 2024022400
nens: 2
Expand All @@ -18,7 +18,6 @@ arguments:
yaml: {{ HOMEgfs }}/ci/cases/yamls/ufs_hybatmDA_defaults.ci.yaml

skip_ci_on_hosts:
- hera
- gaea
- orion
- hercules
Expand Down
2 changes: 1 addition & 1 deletion ci/cases/pr/C96_atm3DVar.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ arguments:
resdetatmos: 96
comroot: {{ 'RUNTESTS' | getenv }}/COMROOT
expdir: {{ 'RUNTESTS' | getenv }}/EXPDIR
icsdir: {{ 'ICSDIR_ROOT' | getenv }}/C96C48
icsdir: {{ 'ICSDIR_ROOT' | getenv }}/C96C48/20240610
idate: 2021122018
edate: 2021122106
nens: 0
Expand Down
2 changes: 1 addition & 1 deletion ci/cases/pr/C96_atm3DVar_extended.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ arguments:
resdetatmos: 96
comroot: {{ 'RUNTESTS' | getenv }}/COMROOT
expdir: {{ 'RUNTESTS' | getenv }}/EXPDIR
icsdir: {{ 'ICSDIR_ROOT' | getenv }}/C96C48
icsdir: {{ 'ICSDIR_ROOT' | getenv }}/C96C48/20240610
idate: 2021122018
edate: 2021122118
nens: 0
Expand Down
8 changes: 4 additions & 4 deletions ci/scripts/utils/rocotostat.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def rocoto_statcount(rocotostat):
rocotostat_output = [line.split()[0:4] for line in rocotostat_output]
rocotostat_output = [line for line in rocotostat_output if len(line) != 1]

status_cases = ['SUCCEEDED', 'FAIL', 'DEAD', 'RUNNING', 'SUBMITTING', 'QUEUED', 'UNAVAILABLE']
status_cases = ['SUCCEEDED', 'FAIL', 'DEAD', 'RUNNING', 'SUBMITTING', 'QUEUED', 'UNAVAILABLE', 'UNKNOWN']

rocoto_status = {}
status_counts = Counter(case for sublist in rocotostat_output for case in sublist)
Expand Down Expand Up @@ -214,14 +214,14 @@ def is_stalled(rocoto_status):
elif rocoto_status['DEAD'] > 0:
error_return = rocoto_status['FAIL'] + rocoto_status['DEAD']
rocoto_state = 'FAIL'
elif 'UNAVAILABLE' in rocoto_status or 'UNKNOWN' in rocoto_status:
elif rocoto_status['UNAVAILABLE'] > 0 or rocoto_status['UNKNOWN'] > 0:
rocoto_status = attempt_multiple_times(lambda: rocoto_statcount(rocotostat), 2, 120, ProcessError)
error_return = 0
rocoto_state = 'RUNNING'
if 'UNAVAILABLE' in rocoto_status:
if rocoto_status['UNAVAILABLE'] > 0:
error_return = rocoto_status['UNAVAILABLE']
rocoto_state = 'UNAVAILABLE'
if 'UNKNOWN' in rocoto_status:
if rocoto_status['UNKNOWN'] > 0:
error_return += rocoto_status['UNKNOWN']
rocoto_state = 'UNKNOWN'
elif is_stalled(rocoto_status):
Expand Down
9 changes: 8 additions & 1 deletion docs/source/errors_faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
Common Errors Known Issues
==========================

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: Reserved Variables Causing Workflow Issues
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Several variables are reserved in the workflow and should not be used as environment variables in your shell. Some of the common ones include (but are not limited to):
``HOMEgfs``, ``machine``, ``ROTDIR``, ``COMROT``, ``COMROOT``, ``COMOUT``, ``COMIN``, ``STMP``, ``PTMP``, ``DATAROOT``, ``DATA``, ``ACCOUNT``, ``PDY``, ``cyc``, ``RUN``, etc.
If you are using any of these variables in your shell, you may encounter unexpected behavior in the workflow.

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: "ImportError" message when running setup script
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -42,4 +50,3 @@ Issue: Directory name change for EnKF folder in ROTDIR
**Issue:** The EnKF ROTDIR folders were renamed during the GFS v15 development process to remove the period between "enkf" and "gdas": enkf.gdas.$PDY → enkfgdas.$PDY

**Fix:** Older tarballs on HPSS will have the older directory name with the period between 'enkf' and 'gdas'. Make sure to rename folder to 'enkfgdas.$PDY' after obtaining. Only an issue for the initial cycle.

5 changes: 3 additions & 2 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

###############
Global Workflow
Global Workflow
###############

**Global-workflow** is the end-to-end workflow designed to run global configurations of medium range weather forecasting for the UFS weather model. It supports both development and operational implementations. In its current format it supports the Global Forecast System (GFS) and the Global Ensemble Forecast System (GEFS) configurations
Expand Down Expand Up @@ -31,7 +31,7 @@ GitHub updates: Users should adjust their "Watch" settings for this repo so they
Table of Contents
=================

.. toctree::
.. toctree::
:numbered:
:maxdepth: 3

Expand All @@ -42,3 +42,4 @@ Table of Contents
output.rst
run.rst
noaa_csp.rst
errors_faq.rst
10 changes: 5 additions & 5 deletions docs/source/init.rst
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,14 @@ Start date = 2021032312
├── enkfgdas.20210323
│   ├── 06
│   │   ├── mem001
│   │   │   └── model_data -> ../../../gdas.20210323/06/model_data
│   │   │   └── model -> ../../../gdas.20210323/06/model
│   │   ├── mem002
│   │   │   └── model_data -> ../../../gdas.20210323/06/model_data
│   │   │   └── model -> ../../../gdas.20210323/06/model
│   │   ├── mem003
│   │   │   └── model_data -> ../../../gdas.20210323/06/model_data
│   │   │   └── model -> ../../../gdas.20210323/06/model
...
│   │   └── mem080
│   │   └── model_data -> ../../../gdas.20210323/06/model_data
│   │   └── model -> ../../../gdas.20210323/06/model
│   └── 12
│   ├── mem001
│   │   └── analysis
Expand All @@ -153,7 +153,7 @@ Start date = 2021032312
│   └── gdas.t12z.ocninc.nc -> ../../../../../gdas.20210323/12/analysis/ocean/gdas.t12z.ocninc.nc
└── gdas.20210323
├── 06
│   └── model_data
│   └── model
│   ├── atmos
│   │   └── restart
│   │   ├── 20210323.120000.ca_data.tile1.nc
Expand Down
1 change: 0 additions & 1 deletion docs/source/run.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,3 @@ Here we will show how you can run an experiment using the Global Workflow. The G
start.rst
monitor_rocoto.rst
view.rst
errors_faq.rst
32 changes: 24 additions & 8 deletions env/AWSPW.env
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ if [[ -n "${ntasks:-}" && -n "${max_tasks_per_node:-}" && -n "${tasks_per_node:-
NTHREADS1=${threads_per_task:-1}
[[ ${NTHREADSmax} -gt ${max_threads_per_task} ]] && NTHREADSmax=${max_threads_per_task}
[[ ${NTHREADS1} -gt ${max_threads_per_task} ]] && NTHREADS1=${max_threads_per_task}
APRUN="${launcher} -n ${ntasks}"
APRUN_default="${launcher} -n ${ntasks}"
else
echo "ERROR config.resources must be sourced before sourcing AWSPW.env"
exit 2
Expand All @@ -43,45 +43,61 @@ if [[ "${step}" = "fcst" ]] || [[ "${step}" = "efcs" ]]; then
export APRUN_UFS="${launcher} -n ${ufs_ntasks}"
unset nnodes ufs_ntasks

elif [[ "${step}" = "waveinit" ]] || [[ "${step}" = "waveprep" ]] || [[ "${step}" = "wavepostsbs" ]] || [[ "${step}" = "wavepostbndpnt" ]] || [[ "${step}" = "wavepostbndpntbll" ]] || [[ "${step}" = "wavepostpnt" ]]; then

export CFP_MP="YES"
if [[ "${step}" = "waveprep" ]]; then export MP_PULSE=0 ; fi
export wavempexec=${launcher}
export wave_mpmd=${mpmd_opt}

elif [[ "${step}" = "post" ]]; then

export NTHREADS_NP=${NTHREADS1}
export APRUN_NP="${APRUN}"
export APRUN_NP="${APRUN_default}"

export NTHREADS_DWN=${threads_per_task_dwn:-1}
[[ ${NTHREADS_DWN} -gt ${max_threads_per_task} ]] && export NTHREADS_DWN=${max_threads_per_task}
export APRUN_DWN="${launcher} -n ${ntasks_dwn}"

elif [[ "${step}" = "atmos_products" ]]; then

export USE_CFP="YES" # Use MPMD for downstream product generation on Hera

elif [[ "${step}" = "oceanice_products" ]]; then

export NTHREADS_OCNICEPOST=${NTHREADS1}
export APRUN_OCNICEPOST="${launcher} -n 1 --cpus-per-task=${NTHREADS_OCNICEPOST}"

elif [[ "${step}" = "ecen" ]]; then

export NTHREADS_ECEN=${NTHREADSmax}
export APRUN_ECEN="${APRUN}"
export APRUN_ECEN="${APRUN_default}"

export NTHREADS_CHGRES=${threads_per_task_chgres:-12}
[[ ${NTHREADS_CHGRES} -gt ${max_tasks_per_node} ]] && export NTHREADS_CHGRES=${max_tasks_per_node}
export APRUN_CHGRES="time"

export NTHREADS_CALCINC=${threads_per_task_calcinc:-1}
[[ ${NTHREADS_CALCINC} -gt ${max_threads_per_task} ]] && export NTHREADS_CALCINC=${max_threads_per_task}
export APRUN_CALCINC="${APRUN}"
export APRUN_CALCINC="${APRUN_default}"

elif [[ "${step}" = "esfc" ]]; then

export NTHREADS_ESFC=${NTHREADSmax}
export APRUN_ESFC="${APRUN}"
export APRUN_ESFC="${APRUN_default}"

export NTHREADS_CYCLE=${threads_per_task_cycle:-14}
[[ ${NTHREADS_CYCLE} -gt ${max_tasks_per_node} ]] && export NTHREADS_CYCLE=${max_tasks_per_node}
export APRUN_CYCLE="${APRUN}"
export APRUN_CYCLE="${APRUN_default}"

elif [[ "${step}" = "epos" ]]; then

export NTHREADS_EPOS=${NTHREADSmax}
export APRUN_EPOS="${APRUN}"
export APRUN_EPOS="${APRUN_default}"

elif [[ "${step}" = "fit2obs" ]]; then

export NTHREADS_FIT2OBS=${NTHREADS1}
export MPIRUN="${APRUN}"
export MPIRUN="${APRUN_default}"

fi
Loading
Loading