SaulLu commited on
Commit
5e3a6e4
β€’
1 Parent(s): bc1d462
Procfile ADDED
@@ -0,0 +1 @@
 
1
+ web: sh setup.sh && streamlit run secure_app.py
README.md CHANGED
@@ -4,8 +4,9 @@ emoji: πŸ¦€
4
  colorFrom: blue
5
  colorTo: purple
6
  sdk: streamlit
7
- app_file: app.py
8
  pinned: false
 
9
  ---
10
 
11
  # Configuration
4
  colorFrom: blue
5
  colorTo: purple
6
  sdk: streamlit
7
+ app_file: secure_app.py
8
  pinned: false
9
+ sdk_version : 1.0.0
10
  ---
11
 
12
  # Configuration
apps/__init__.py ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from apps.home_app import HomeApp
2
+ from apps.walsh_app import WalshApp
3
+ from apps.walsh_app_secure import WalshAppSecure
4
+ from apps.login_app import LoginApp
5
+ from apps.solar_mach import SolarMach
6
+ from apps.spacy_nlp import SpacyNLP
7
+ from apps.uber_app import UberNYC
8
+ from apps.cheat_app import CheatApp
9
+ from apps.myloading_app import MyLoadingApp
10
+ from apps.signup import SignUpApp
11
+ from apps.cookie_cutter import CookieCutterApp
12
+ from apps.load_app import LoaderTestApp
apps/cheat_app.py ADDED
@@ -0,0 +1,266 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Streamlit Cheat Sheet
3
+ App to summarise streamlit docs v0.81.0 for quick reference
4
+ There is also an accompanying png version
5
+ https://github.com/daniellewisDL/streamlit-cheat-sheet
6
+ v0.71.0 November 2020 Daniel Lewis and Austin Chen
7
+ """
8
+
9
+ import streamlit as st
10
+ from pathlib import Path
11
+ import base64
12
+ from hydralit import HydraHeadApp
13
+
14
+
15
+ # Thanks to streamlitopedia for the following code snippet
16
+ def img_to_bytes(img_path):
17
+ img_bytes = Path(img_path).read_bytes()
18
+ encoded = base64.b64encode(img_bytes).decode()
19
+ return encoded
20
+
21
+
22
+
23
+ class CheatApp(HydraHeadApp):
24
+
25
+ def __init__(self, title = '', **kwargs):
26
+ self.__dict__.update(kwargs)
27
+ self.title = title
28
+
29
+ def run(self):
30
+
31
+ self._cs_sidebar()
32
+ self._cs_body()
33
+
34
+
35
+ # sidebar
36
+
37
+ def _cs_sidebar(self):
38
+
39
+ st.sidebar.header('Streamlit cheat sheet')
40
+
41
+ st.sidebar.markdown('''
42
+ <small>Summary of the [docs](https://docs.streamlit.io/en/stable/api.html), as of [Streamlit v0.81.0](https://www.streamlit.io/).</small>
43
+ ''', unsafe_allow_html=True)
44
+
45
+ st.sidebar.markdown('__How to install and import__')
46
+
47
+ st.sidebar.code('$ pip install streamlit')
48
+
49
+ st.sidebar.markdown('Import convention')
50
+ st.sidebar.code('>>> import streamlit as st')
51
+
52
+ st.sidebar.markdown('__Add widgets to sidebar__')
53
+ st.sidebar.code('''
54
+ st.sidebar.<widget>
55
+ >>> a = st.sidebar.radio(\'R:\',[1,2])
56
+ ''')
57
+
58
+ st.sidebar.markdown('__Command line__')
59
+ st.sidebar.code('''
60
+ $ streamlit --help
61
+ $ streamlit run your_script.py
62
+ $ streamlit hello
63
+ $ streamlit config show
64
+ $ streamlit cache clear
65
+ $ streamlit docs
66
+ $ streamlit --version
67
+ ''')
68
+
69
+ st.sidebar.markdown('__Pre-release features__')
70
+ st.sidebar.markdown('[Beta and experimental features](https://docs.streamlit.io/en/0.70.0/api.html#beta-and-experimental-features)')
71
+ st.sidebar.code('''
72
+ pip uninstall streamlit
73
+ pip install streamlit-nightly --upgrade
74
+ ''')
75
+
76
+ st.sidebar.markdown('''[<img src='data:image/png;base64,{}' class='img-fluid' width=32 height=32>](https://github.com/daniellewisDL/streamlit-cheat-sheet) <small>st.cheat_sheet v0.81.0 | May 2021</small>'''.format(img_to_bytes("./resources/brain.png")), unsafe_allow_html=True)
77
+
78
+ return None
79
+
80
+ ##########################
81
+ # Main body of cheat sheet
82
+ ##########################
83
+
84
+ def _cs_body(self):
85
+ # Magic commands
86
+
87
+ st.subheader('Source for this great app is from the Streamlit gallery [Streamlit Cheat Sheet](https://github.com/daniellewisDL/streamlit-cheat-sheet). An example of how easy it is to convert an existing application and use within a Hydralit multi-page application, see the secret saurce [here] (https://github.com/TangleSpace/hydralit).')
88
+ st.markdown('<br><br>',unsafe_allow_html=True)
89
+
90
+ col1, col2, col3 = st.columns(3)
91
+
92
+ col1.subheader('Magic commands')
93
+ col1.code('''# Magic commands implicitly `st.write()`
94
+ \'\'\' _This_ is some __Markdown__ \'\'\'
95
+ a=3
96
+ 'dataframe:', data
97
+ ''')
98
+
99
+ # Display text
100
+
101
+ col1.subheader('Display text')
102
+ col1.code('''
103
+ st.text('Fixed width text')
104
+ st.markdown('_Markdown_') # see *
105
+ st.latex(r\'\'\' e^{i\pi} + 1 = 0 \'\'\')
106
+ st.write('Most objects') # df, err, func, keras!
107
+ st.write(['st', 'is <', 3]) # see *
108
+ st.title('My title')
109
+ st.header('My header')
110
+ st.subheader('My sub')
111
+ st.code('for i in range(8): foo()')
112
+ * optional kwarg unsafe_allow_html = True
113
+ ''')
114
+
115
+ # Display data
116
+
117
+ col1.subheader('Display data')
118
+ col1.code('''
119
+ st.dataframe(my_dataframe)
120
+ st.table(data.iloc[0:10])
121
+ st.json({'foo':'bar','fu':'ba'})
122
+ ''')
123
+
124
+ # Display charts
125
+
126
+ col1.subheader('Display charts')
127
+ col1.code('''
128
+ st.line_chart(data)
129
+ st.area_chart(data)
130
+ st.bar_chart(data)
131
+ st.pyplot(fig)
132
+ st.altair_chart(data)
133
+ st.vega_lite_chart(data)
134
+ st.plotly_chart(data)
135
+ st.bokeh_chart(data)
136
+ st.pydeck_chart(data)
137
+ st.deck_gl_chart(data)
138
+ st.graphviz_chart(data)
139
+ st.map(data)
140
+ ''')
141
+
142
+ # Display media
143
+
144
+ col1.subheader('Display media')
145
+ col1.code('''
146
+ st.image('./header.png')
147
+ st.audio(data)
148
+ st.video(data)
149
+ ''')
150
+
151
+ # Display interactive widgets
152
+
153
+ col2.subheader('Display interactive widgets')
154
+ col2.code('''
155
+ st.button('Hit me')
156
+ st.checkbox('Check me out')
157
+ st.radio('Radio', [1,2,3])
158
+ st.selectbox('Select', [1,2,3])
159
+ st.multiselect('Multiselect', [1,2,3])
160
+ st.slider('Slide me', min_value=0, max_value=10)
161
+ st.select_slider('Slide to select', options=[1,'2'])
162
+ st.text_input('Enter some text')
163
+ st.number_input('Enter a number')
164
+ st.text_area('Area for textual entry')
165
+ st.date_input('Date input')
166
+ st.time_input('Time entry')
167
+ st.file_uploader('File uploader')
168
+ st.color_picker('Pick a color')
169
+ ''')
170
+ col2.write('Use widgets\' returned values in variables:')
171
+ col2.code('''
172
+ >>> for i in range(int(st.number_input('Num:'))): foo()
173
+ >>> if st.sidebar.selectbox('I:',['f']) == 'f': b()
174
+ >>> my_slider_val = st.slider('Quinn Mallory', 1, 88)
175
+ >>> st.write(slider_val)
176
+ ''')
177
+
178
+ # Control flow
179
+
180
+ col2.subheader('Control flow')
181
+ col2.code('''
182
+ st.stop()
183
+ ''')
184
+
185
+ # Lay out your app
186
+
187
+ col2.subheader('Lay out your app')
188
+ col2.code('''
189
+ st.container()
190
+ st.columns(spec)
191
+ >>> col1, col2 = st.columns(2)
192
+ >>> col1.subheader('Columnisation')
193
+ st.expander('Expander')
194
+ >>> with st.expander('Expand'):
195
+ >>> st.write('Juicy deets')
196
+ ''')
197
+
198
+
199
+ # Display code
200
+
201
+ col2.subheader('Display code')
202
+ col2.code('''
203
+ st.echo()
204
+ >>> with st.echo():
205
+ >>> st.write('Code will be executed and printed')
206
+ ''')
207
+
208
+ # Display progress and status
209
+
210
+ col3.subheader('Display progress and status')
211
+ col3.code('''
212
+ st.progress(progress_variable_1_to_100)
213
+ st.spinner()
214
+ >>> with st.spinner(text='In progress'):
215
+ >>> time.sleep(5)
216
+ >>> st.success('Done')
217
+ st.balloons()
218
+ st.error('Error message')
219
+ st.warning('Warning message')
220
+ st.info('Info message')
221
+ st.success('Success message')
222
+ st.exception(e)
223
+ ''')
224
+
225
+ # Placeholders, help, and options
226
+
227
+ col3.subheader('Placeholders, help, and options')
228
+ col3.code('''
229
+ st.empty()
230
+ >>> my_placeholder = st.empty()
231
+ >>> my_placeholder.text('Replaced!')
232
+ st.help(pandas.DataFrame)
233
+ st.get_option(key)
234
+ st.set_option(key, value)
235
+ st.set_page_config(layout='wide')
236
+ ''')
237
+
238
+ # Mutate data
239
+
240
+ col3.subheader('Mutate data')
241
+ col3.code('''
242
+ DeltaGenerator.add_rows(data)
243
+ >>> my_table = st.table(df1)
244
+ >>> my_table.add_rows(df2)
245
+ >>> my_chart = st.line_chart(df1)
246
+ >>> my_chart.add_rows(df2)
247
+ ''')
248
+
249
+ # Optimize performance
250
+
251
+ col3.subheader('Optimize performance')
252
+ col3.code('''
253
+ @st.cache
254
+ >>> @st.cache
255
+ ... def foo(bar):
256
+ ... # Mutate bar
257
+ ... return data
258
+ >>> # Executes d1 as first time
259
+ >>> d1 = foo(ref1)
260
+ >>> # Does not execute d1; returns cached value, d1==d2
261
+ >>> d2 = foo(ref1)
262
+ >>> # Different arg, so function d1 executes
263
+ >>> d3 = foo(ref2)
264
+ ''')
265
+
266
+ return None
apps/cookie_cutter.py ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from hydralit import HydraHeadApp
3
+ from hydralit_components import CookieManager
4
+
5
+
6
+ class CookieCutterApp(HydraHeadApp):
7
+
8
+ def __init__(self, title = 'Loader', delay=0, **kwargs):
9
+ self.__dict__.update(kwargs)
10
+ self.title = title
11
+ self.delay = delay
12
+
13
+ def run(self):
14
+
15
+ try:
16
+ #cookie_manager = stx.CookieManager(key='1234')
17
+ cookie_manager = CookieManager(key='REDKI')
18
+
19
+ st.subheader("All Cookies:")
20
+ cookies = cookie_manager.get_all()
21
+ st.write(cookies)
22
+
23
+ c1, c2, c3 = st.columns(3)
24
+ with c1:
25
+ st.subheader("Get Cookie:")
26
+ cookie = st.text_input("Cookie", key="0")
27
+ clicked = st.button("Get")
28
+ if clicked:
29
+ value = cookie_manager.get(cookie)
30
+ st.write(value)
31
+ with c2:
32
+ st.subheader("Set Cookie:")
33
+ cookie = st.text_input("Cookie", key="1")
34
+ val = st.text_input("Value")
35
+ if st.button("Add"):
36
+ cookie_manager.set(cookie, val)
37
+ with c3:
38
+ st.subheader("Delete Cookie:")
39
+ cookie = st.text_input("Cookie", key="2")
40
+ if st.button("Delete"):
41
+ cookie_manager.delete(cookie)
42
+
43
+
44
+ except Exception as e:
45
+ st.image("./resources/failure.png",width=100,)
46
+ st.error('An error has occurred, someone will be punished for your inconvenience, we humbly request you try again.')
47
+ st.error('Error details: {}'.format(e))
apps/extras/__init__.py ADDED
File without changes
apps/extras/backmapping.py ADDED
@@ -0,0 +1,347 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # backmapping.py
2
+ import streamlit as st
3
+ import math
4
+ from copy import deepcopy
5
+
6
+ import matplotlib.patches as mpatches
7
+ import matplotlib.pyplot as plt
8
+ import numpy as np
9
+ import pandas as pd
10
+ import scipy.constants as const
11
+ from matplotlib.legend_handler import HandlerPatch
12
+ from sunpy import log
13
+ from sunpy.coordinates import frames
14
+ from sunpy.coordinates import get_horizons_coord
15
+
16
+ from apps.extras.selected_bodies import body_dict
17
+
18
+ plt.rcParams['axes.linewidth'] = 1.5
19
+ plt.rcParams['font.size'] = 15
20
+ plt.rcParams['agg.path.chunksize'] = 20000
21
+
22
+ pd.options.display.max_rows = None
23
+ pd.options.display.float_format = '{:.1f}'.format
24
+
25
+ # disable unnecessary logging
26
+ log.setLevel('WARNING')
27
+
28
+
29
+ def print_body_list():
30
+ """
31
+ prints a selection of body keys and the corresponding body names which may be provided to the
32
+ HeliosphericConstellation class
33
+ """
34
+ # print('Please visit https://ssd.jpl.nasa.gov/horizons.cgi?s_target=1#top for a complete list of available bodies')
35
+ data = pd.DataFrame\
36
+ .from_dict(body_dict, orient='index', columns=['ID', 'Body', 'Color'])\
37
+ .drop(['ID', 'Color'], 'columns')\
38
+ .drop_duplicates()
39
+ data.index.name = 'Key'
40
+ return data
41
+
42
+
43
+ class HeliosphericConstellation():
44
+ """
45
+ Class which handles the selected bodies
46
+ Parameters
47
+ ----------
48
+ date: str
49
+ body_list: list
50
+ list of body keys to be used. Keys can be string of int.
51
+ vsw_list: list, optional
52
+ list of solar wind speeds at the position of the different bodies. Must have the same length as body_list.
53
+ Default is an epmty list leading to vsw=400km/s used for every body.
54
+ reference_long: float, optional
55
+ Carrington longitute of reference position at the Sun
56
+ reference_lat: float, optional
57
+ Heliographic latitude of referene position at the Sun
58
+ """
59
+
60
+ def __init__(self, date, body_list, vsw_list=[], reference_long=None, reference_lat=None):
61
+ body_list = list(dict.fromkeys(body_list))
62
+ bodies = deepcopy(body_dict)
63
+
64
+ self.date = date
65
+ self.reference_long = reference_long
66
+ self.reference_lat = reference_lat
67
+
68
+ pos_E = get_horizons_coord(399, self.date, 'id') # (lon, lat, radius) in (deg, deg, AU)
69
+ self.pos_E = pos_E.transform_to(frames.HeliographicCarrington(observer='Sun'))
70
+
71
+ if len(vsw_list) == 0:
72
+ vsw_list = np.zeros(len(body_list)) + 400
73
+
74
+ random_cols = ['forestgreen', 'mediumblue', 'm', 'saddlebrown', 'tomato', 'olive', 'steelblue', 'darkmagenta',
75
+ 'c', 'darkslategray', 'yellow', 'darkolivegreen']
76
+ body_lon_list = []
77
+ body_lat_list = []
78
+ body_dist_list = []
79
+ longsep_E_list = []
80
+ latsep_E_list = []
81
+ body_vsw_list = []
82
+ footp_long_list = []
83
+ longsep_list = []
84
+ latsep_list = []
85
+ footp_longsep_list = []
86
+
87
+ for i, body in enumerate(body_list.copy()):
88
+ if body in bodies:
89
+ body_id = bodies[body][0]
90
+ body_lab = bodies[body][1]
91
+ body_color = bodies[body][2]
92
+
93
+ else:
94
+ body_id = body
95
+ body_lab = str(body)
96
+ body_color = random_cols[i]
97
+ bodies.update(dict.fromkeys([body_id], [body_id, body_lab, body_color]))
98
+
99
+ try:
100
+ pos = get_horizons_coord(body_id, date, 'id') # (lon, lat, radius) in (deg, deg, AU)
101
+ pos = pos.transform_to(frames.HeliographicCarrington(observer='Sun'))
102
+ bodies[body_id].append(pos)
103
+ bodies[body_id].append(vsw_list[i])
104
+
105
+ longsep_E = pos.lon.value - self.pos_E.lon.value
106
+ if longsep_E > 180:
107
+ longsep_E = longsep_E - 360.
108
+ latsep_E = pos.lat.value - self.pos_E.lat.value
109
+
110
+ body_lon_list.append(pos.lon.value)
111
+ body_lat_list.append(pos.lat.value)
112
+ body_dist_list.append(pos.radius.value)
113
+ longsep_E_list.append(longsep_E)
114
+ latsep_E_list.append(latsep_E)
115
+
116
+ body_vsw_list.append(vsw_list[i])
117
+
118
+ sep, alpha = self.backmapping(pos, date, reference_long, vsw=vsw_list[i])
119
+ bodies[body_id].append(sep)
120
+
121
+ body_footp_long = pos.lon.value + alpha
122
+ if body_footp_long > 360:
123
+ body_footp_long = body_footp_long - 360
124
+ footp_long_list.append(body_footp_long)
125
+
126
+ if self.reference_long is not None:
127
+ bodies[body_id].append(sep)
128
+ long_sep = pos.lon.value - self.reference_long
129
+ if long_sep > 180:
130
+ long_sep = long_sep - 360.
131
+
132
+ longsep_list.append(long_sep)
133
+ footp_longsep_list.append(sep)
134
+
135
+ if self.reference_lat is not None:
136
+ lat_sep = pos.lat.value - self.reference_lat
137
+ latsep_list.append(lat_sep)
138
+ except ValueError:
139
+ print('')
140
+ print('!!! No ephemeris for target "' + str(body) + '" for date ' + self.date)
141
+ st.warning('No ephemeris for target "' + str(body) + '" for date ' + self.date)
142
+ body_list.remove(body)
143
+
144
+ body_dict_short = {sel_key: bodies[sel_key] for sel_key in body_list}
145
+ self.body_dict = body_dict_short
146
+ self.max_dist = np.max(body_dist_list)
147
+ self.coord_table = pd.DataFrame(
148
+ {'Spacecraft/Body': list(self.body_dict.keys()), 'Carrington Longitude (Β°)': body_lon_list,
149
+ 'Latitude (Β°)': body_lat_list, 'Heliocentric Distance (AU)': body_dist_list,
150
+ "Longitudinal separation to Earth's longitude": longsep_E_list,
151
+ "Latitudinal separation to Earth's latitude": latsep_E_list, 'Vsw': body_vsw_list,
152
+ 'Magnetic footpoint longitude (Carrington)': footp_long_list})
153
+
154
+ if self.reference_long is not None:
155
+ self.coord_table['Longitudinal separation between body and reference_long'] = longsep_list
156
+ self.coord_table[
157
+ "Longitudinal separation between body's mangetic footpoint and reference_long"] = footp_longsep_list
158
+ if self.reference_lat is not None:
159
+ self.coord_table['Latitudinal separation between body and reference_lat'] = latsep_list
160
+
161
+ pass
162
+ self.coord_table.style.set_properties(**{'text-align': 'left'})
163
+
164
+ def backmapping(self, body_pos, date, reference_long, vsw=400):
165
+ """
166
+ Determine the longitudinal separation angle of a given spacecraft and a given reference longitude
167
+ Parameters
168
+ ----------
169
+ body_pos : astropy.coordinates.sky_coordinate.SkyCoord
170
+ coordinate of the body in Carrington coordinates
171
+ date: str
172
+ e.g., '2020-03-22 12:30'
173
+ reference_long: float
174
+ Carrington longitude of reference point at Sun to which we determine the longitudinal separation
175
+ vsw: float
176
+ solar wind speed (km/s) used to determine the position of the magnetic footpoint of the body. Default is 400.
177
+ out:
178
+ sep: float
179
+ longitudinal separation of body magnetic footpoint and reference longitude in degrees
180
+ alpha: float
181
+ backmapping angle
182
+ """
183
+ AU = const.au / 1000 # km
184
+
185
+ pos = body_pos
186
+ lon = pos.lon.value
187
+ dist = pos.radius.value
188
+
189
+ omega = math.radians(360. / (25.38 * 24 * 60 * 60)) # rot-angle in rad/sec, sidereal period
190
+
191
+ tt = dist * AU / vsw
192
+ alpha = math.degrees(omega * tt)
193
+
194
+ if reference_long is not None:
195
+ sep = (lon + alpha) - reference_long
196
+ if sep > 180.:
197
+ sep = sep - 360
198
+
199
+ if sep < -180.:
200
+ sep = 360 - abs(sep)
201
+ else:
202
+ sep = np.nan
203
+
204
+ return sep, alpha
205
+
206
+ def plot(self, plot_spirals=True, plot_sun_body_line=False, show_earth_centered_coord=True, reference_vsw=400, transparent=False, outfile=''):
207
+ """
208
+ Make a polar plot showing the Sun in the center (view from North) and the positions of the selected bodies
209
+ Parameters
210
+ ----------
211
+ plot_spirals: bool
212
+ if True, the magnetic field lines connecting the bodies with the Sun are plotted
213
+ plot_sun_body_line: bool
214
+ if True, straight lines connecting the bodies with the Sun are plotted
215
+ show_earth_centered_coord: bool
216
+ if True, additional longitudinal tickmarks are shown with Earth at longitude 0
217
+ reference_vsw: int
218
+ if defined, defines solar wind speed for reference. if not defined, 400 km/s is used
219
+ outfile: string
220
+ if provided, the plot is saved with outfile as filename
221
+ """
222
+ import pylab as pl
223
+ AU = const.au / 1000 # km
224
+
225
+ fig, ax = plt.subplots(subplot_kw=dict(projection='polar'), figsize=(12, 8))
226
+ self.ax = ax
227
+
228
+ r = np.arange(0.007, self.max_dist + 0.3, 0.001)
229
+ omega = np.radians(360. / (25.38 * 24 * 60 * 60)) # solar rot-angle in rad/sec, sidereal period
230
+
231
+ for i, body_id in enumerate(self.body_dict):
232
+ body_lab = self.body_dict[body_id][1]
233
+ body_color = self.body_dict[body_id][2]
234
+ body_vsw = self.body_dict[body_id][4]
235
+ body_pos = self.body_dict[body_id][3]
236
+
237
+ pos = body_pos
238
+ dist_body = pos.radius.value
239
+ body_long = pos.lon.value
240
+
241
+ E_long = self.pos_E.lon.value
242
+ dist_e = self.pos_E.radius.value
243
+
244
+ # plot body positions
245
+ ax.plot(np.deg2rad(body_long), dist_body, 's', color=body_color, label=body_lab)
246
+ if plot_sun_body_line:
247
+ # ax.plot(alpha_ref[0], 0.01, 0)
248
+ ax.plot([np.deg2rad(body_long), np.deg2rad(body_long)], [0.01, dist_body], ':', color=body_color)
249
+ # plot the spirals
250
+ if plot_spirals:
251
+ tt = dist_body * AU / body_vsw
252
+ alpha = np.degrees(omega * tt)
253
+ alpha_body = np.deg2rad(body_long) + omega / (body_vsw / AU) * (dist_body - r)
254
+ ax.plot(alpha_body, r, color=body_color)
255
+
256
+ if self.reference_long is not None:
257
+ delta_ref = self.reference_long
258
+ if delta_ref < 0.:
259
+ delta_ref = delta_ref + 360.
260
+ alpha_ref = np.deg2rad(delta_ref) + omega / (reference_vsw / AU) * (dist_e / AU - r) - (
261
+ omega / (reference_vsw / AU) * (dist_e / AU))
262
+ # old arrow style:
263
+ # arrow_dist = min([self.max_dist + 0.1, 2.])
264
+ # ref_arr = plt.arrow(alpha_ref[0], 0.01, 0, arrow_dist, head_width=0.12, head_length=0.11, edgecolor='black',
265
+ # facecolor='black', lw=2, zorder=5, overhang=0.2)
266
+ arrow_dist = min([self.max_dist/3.2, 2.])
267
+ ref_arr = plt.arrow(alpha_ref[0], 0.01, 0, arrow_dist, head_width=0.2, head_length=0.07, edgecolor='black',
268
+ facecolor='black', lw=1.8, zorder=5, overhang=0.2)
269
+
270
+ if plot_spirals:
271
+ ax.plot(alpha_ref, r, '--k', label=f'field line connecting to\nref. long. (vsw={reference_vsw} km/s)')
272
+
273
+ leg1 = ax.legend(loc=(1.2, 0.7), fontsize=13)
274
+ if self.reference_long is not None:
275
+ def legend_arrow(width, height, **_):
276
+ return mpatches.FancyArrow(0, 0.5 * height, width, 0, length_includes_head=True,
277
+ head_width=0.75 * height)
278
+
279
+ leg2 = ax.legend([ref_arr], ['reference long.'], loc=(1.2, 0.6),
280
+ handler_map={mpatches.FancyArrow: HandlerPatch(patch_func=legend_arrow), },
281
+ fontsize=13)
282
+ ax.add_artist(leg1)
283
+
284
+ ax.set_rlabel_position(E_long + 120)
285
+ ax.set_theta_offset(np.deg2rad(270 - E_long))
286
+ ax.set_rmax(self.max_dist + 0.3)
287
+ ax.set_rmin(0.01)
288
+ ax.yaxis.get_major_locator().base.set_params(nbins=4)
289
+ circle = plt.Circle((0., 0.), self.max_dist + 0.29, transform=ax.transData._b, edgecolor="k", facecolor=None,
290
+ fill=False, lw=2)
291
+ ax.add_patch(circle)
292
+
293
+ # manually plot r-grid lines with different resolution depending on maximum distance bodyz
294
+ # st.sidebar.info(self.max_dist)
295
+ if self.max_dist < 2:
296
+ ax.set_rgrids(np.arange(0, self.max_dist + 0.29, 0.5)[1:], angle=22.5)
297
+ # st.sidebar.info(str(np.arange(0, self.max_dist + 0.29, 0.5)))
298
+ else:
299
+ if self.max_dist < 10:
300
+ ax.set_rgrids(np.arange(0, self.max_dist + 0.29, 1.0)[1:], angle=22.5)
301
+ # st.sidebar.info(str(np.arange(0, self.max_dist + 0.29, 1.0)))
302
+
303
+ ax.set_title(self.date + '\n', pad=60)
304
+
305
+ plt.tight_layout()
306
+ plt.subplots_adjust(bottom=0.15)
307
+
308
+ if show_earth_centered_coord:
309
+ pos1 = ax.get_position() # get the original position of the polar plot
310
+ offset = 0.12
311
+ pos2 = [pos1.x0 - offset / 2, pos1.y0 - offset / 2, pos1.width + offset, pos1.height + offset]
312
+ ax2 = self._polar_twin(ax, E_long, pos2)
313
+
314
+ ax.tick_params(axis='x', pad=10)
315
+
316
+ ax.text(0.94, 0.16, 'Solar-MACH',
317
+ fontfamily='DejaVu Serif', fontsize=28,
318
+ ha='right', va='bottom', transform=fig.transFigure)
319
+ ax.text(0.94, 0.12, 'https://solar-mach.github.io',
320
+ fontfamily='DejaVu Sans', fontsize=18,
321
+ ha='right', va='bottom', transform=fig.transFigure)
322
+
323
+ if transparent:
324
+ fig.patch.set_alpha(0.0)
325
+
326
+ if outfile != '':
327
+ plt.savefig(outfile)
328
+ st.pyplot(fig)
329
+
330
+ def _polar_twin(self, ax, E_long, position):
331
+ """
332
+ add an additional axes which is needed to plot additional longitudinal tickmarks with Earth at longitude 0
333
+ """
334
+ ax2 = ax.figure.add_axes(position, projection='polar',
335
+ label='twin', frameon=False,
336
+ theta_direction=ax.get_theta_direction(),
337
+ theta_offset=E_long)
338
+
339
+ ax2.set_rmax(self.max_dist + 0.3)
340
+ ax2.yaxis.set_visible(False)
341
+ ax2.set_theta_zero_location("S")
342
+ ax2.tick_params(axis='x', colors='darkgreen', pad=10)
343
+ gridlines = ax2.xaxis.get_gridlines()
344
+ for xax in gridlines:
345
+ xax.set_color('darkgreen')
346
+
347
+ return ax2
apps/extras/models.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "zh_core_web_sm":"Chinese (zh_core_web_sm)",
3
+ "zh_core_web_trf":"Chinese (zh_core_web_trf)",
4
+ "da_core_news_sm":"Danish (da_core_news_sm)",
5
+ "nl_core_news_sm":"Dutch (nl_core_news_sm)",
6
+ "en_core_web_sm":"English (en_core_web_sm)",
7
+ "en_core_web_trf":"English (en_core_web_trf)",
8
+ "fr_core_news_sm":"French (fr_core_news_sm)",
9
+ "de_core_news_sm":"German (de_core_news_sm)",
10
+ "el_core_news_sm":"Greek (el_core_news_sm)",
11
+ "it_core_news_sm":"Italian (it_core_news_sm)",
12
+ "ja_core_news_sm":"Japanese (ja_core_news_sm)",
13
+ "lt_core_news_sm":"Lithuanian (lt_core_news_sm)",
14
+ "mk_core_news_sm":"Macedonian (mk_core_news_sm)",
15
+ "nb_core_news_sm":"Norwegian (nb_core_news_sm)",
16
+ "pl_core_news_sm":"Polish (pl_core_news_sm)",
17
+ "pl_core_news_md":"Polish (pl_core_news_md)",
18
+ "pt_core_news_sm":"Portuguese (pt_core_news_sm)",
19
+ "pt_core_news_md":"Portuguese (pt_core_news_md)",
20
+ "ro_core_news_sm":"Romanian (ro_core_news_sm)",
21
+ "ru_core_news_sm":"Russian (ru_core_news_sm)",
22
+ "es_core_news_sm":"Spanish (es_core_news_sm)"
23
+ }
apps/extras/selected_bodies.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # selected_bodies.py
2
+
3
+ # initialize the body dictionary
4
+ body_dict = dict.fromkeys(['Mercury', 199], [199, 'Mercury', 'darkturquoise'])
5
+ body_dict.update(dict.fromkeys(['Venus', 299], [299, 'Venus', 'darkorchid']))
6
+ body_dict.update(dict.fromkeys(['Earth', 'EARTH', 'earth',399], [399, 'Earth', 'green']))
7
+ body_dict.update(dict.fromkeys(['Mars', 499], [499, 'Mars', 'maroon']))
8
+ body_dict.update(dict.fromkeys(['Jupiter', 599], [599, 'Jupiter', 'navy']))
9
+
10
+ body_dict.update(dict.fromkeys(['STEREO B', 'STEREO-B', 'STB', 'stb', -235], [-235, 'STEREO B', 'b']))
11
+ body_dict.update(dict.fromkeys(['STEREO A', 'STEREO-A', 'STA', 'sta', -234], [-234, 'STEREO A', 'red']))
12
+ body_dict.update(dict.fromkeys(['SOHO', 'soho', -21], [-21, 'SOHO', 'darkgreen']))
13
+ body_dict.update(dict.fromkeys(['Solar Orbiter', 'SolO', 'solarorbiter', 'SolarOrbiter', -144], [-144, 'Solar Orbiter', 'dodgerblue']))
14
+ body_dict.update(dict.fromkeys(['PSP', 'Parker Solar Probe', 'parkersolarprobe', 'ParkerSolarProbe', -96], [-96, 'Parker Solar Probe', 'purple']))
15
+ body_dict.update(dict.fromkeys(['BepiColombo', 'Bepi', 'MPO', -121], [-121, 'BepiColombo', 'orange']))
16
+ body_dict.update(dict.fromkeys(['MAVEN', -202], [-202, 'MAVEN', 'brown']))
17
+ body_dict.update(dict.fromkeys(['Mars Express', -41], [-41, 'Mars Express', 'darkorange']))
18
+ body_dict.update(dict.fromkeys(['MESSENGER', -236], [-236, 'MESSENGER', 'olivedrab']))
19
+ body_dict.update(dict.fromkeys(['Juno', -61], [-61, 'Juno', 'orangered']))
20
+ body_dict.update(dict.fromkeys(['Cassini', -82], [-82, 'Cassini', 'mediumvioletred']))
21
+ body_dict.update(dict.fromkeys(['Rosetta', -226], [-226, 'Rosetta', 'blueviolet']))
22
+ body_dict.update(dict.fromkeys(['Pioneer10', -23], [-23, 'Pioneer 10', 'teal']))
23
+ body_dict.update(dict.fromkeys(['Pioneer11', -24], [-24, 'Pioneer 11', 'darkblue']))
24
+ body_dict.update(dict.fromkeys(['Ulysses', -55], [-55, 'Ulysses', 'dimgray']))
25
+ body_dict.update(dict.fromkeys(['Voyager1', -31], [-31, 'Voyager 1', 'darkred']))
26
+ body_dict.update(dict.fromkeys(['Voyager2', -32], [-32, 'Voyager 2', 'midnightblue']))
apps/home_app.py ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import streamlit as st
3
+ from hydralit import HydraHeadApp
4
+
5
+ MENU_LAYOUT = [1,1,1,7,2]
6
+
7
+ class HomeApp(HydraHeadApp):
8
+
9
+
10
+ def __init__(self, title = 'Hydralit Explorer', **kwargs):
11
+ self.__dict__.update(kwargs)
12
+ self.title = title
13
+
14
+
15
+ #This one method that must be implemented in order to be used in a Hydralit application.
16
+ #The application must also inherit from the hydrapp class in order to correctly work within Hydralit.
17
+ def run(self):
18
+
19
+ try:
20
+ st.markdown("<h1 style='text-align:center;padding: 0px 0px;color:black;font-size:200%;'>Home</h1>",unsafe_allow_html=True)
21
+ st.markdown("<h2 style='text-align: center;'>This example was written using the <a href = https://github.com/TangleSpace/hydralit>Hydralit</a> library. Sourecode for this example is located <a href = https://github.com/TangleSpace/hydralit-example>here</a>.</h2>",unsafe_allow_html=True)
22
+
23
+ col_header_logo_left_far, col_header_logo_left,col_header_text,col_header_logo_right,col_header_logo_right_far = st.columns([1,2,2,2,1])
24
+
25
+ #col_header_logo_right_far.image(os.path.join(".","resources","hydra.png"),width=100,)
26
+
27
+ if col_header_text.button('This will open a new tab and go'):
28
+ self.do_redirect("https://hotstepper.readthedocs.io/index.html")
29
+
30
+ _,_,col_logo, col_text,_ = st.columns(MENU_LAYOUT)
31
+ col_logo.image(os.path.join(".","resources","data.png"),width=80,)
32
+ col_text.subheader("This explorer has multiple applications, each application could be run individually, however where is the fun in that? Below is a sample home page.")
33
+
34
+ st.markdown('<br><br>',unsafe_allow_html=True)
35
+
36
+
37
+ _,_,col_logo, col_text,col_btn = st.columns(MENU_LAYOUT)
38
+ # if col_text.button('Cheat Sheet ➑️'):
39
+ # self.do_redirect('Cheat Sheet')
40
+ col_logo.image(os.path.join(".","resources","classroom.png"),width=50,)
41
+ col_text.info("This application is all credit to [streamlit cheat sheet](https://github.com/daniellewisDL/streamlit-cheat-sheet), this is an example of how quickly an existing application can be wrapped in a HydraHeadAPP class and used in Hydralit.")
42
+
43
+ #The sample content in a sub-section with jump to format.
44
+ _,_,col_logo, col_text,col_btn = st.columns(MENU_LAYOUT)
45
+ # if col_text.button('Sequency Denoising ➑️'):
46
+ # self.do_redirect('Sequency Denoising')
47
+
48
+ col_logo.image(os.path.join(".","resources","denoise.png"),width=50,)
49
+ col_text.info("This application is a quick look at some analysis of vessel queue data with discrete denoising using Sequency methods as provided by the [Hotstepper](https://github.com/TangleSpace/hotstepper) package.")
50
+
51
+ _,_,col_logo, col_text,col_btn = st.columns(MENU_LAYOUT)
52
+ # if col_text.button('Solar Mach ➑️'):
53
+ # self.do_redirect('Solar Mach')
54
+ col_logo.image(os.path.join(".","resources","satellite.png"),width=50,)
55
+ col_text.info("This application is all credit to [Solar-MACH](https://github.com/jgieseler/Solar-MACH), this is an example of how quickly an existing application can be wrapped in a HydraHeadAPP class and used in Hydralit.")
56
+
57
+ _,_,col_logo, col_text,col_btn = st.columns(MENU_LAYOUT)
58
+ # if col_text.button('Spacy NLP ➑️'):
59
+ # self.do_redirect('Spacy NLP')
60
+ col_logo.image(os.path.join(".","resources","belgium.png"),width=50,)
61
+ col_text.info("This application is all credit to [spacy-streamlit-demo](https://github.com/ines/spacy-streamlit-demo), this is an example of how quickly an existing application can be wrapped in a HydraHeadAPP class and used in Hydralit.")
62
+
63
+ _,_,col_logo, col_text,col_btn = st.columns(MENU_LAYOUT)
64
+ # if col_text.button('Uber Pickups ➑️'):
65
+ # self.do_redirect('Uber Pickups')
66
+ col_logo.image(os.path.join(".","resources","taxi.png"),width=50,)
67
+ col_text.info("This application is all credit to [demo-uber-nyc-pickups](https://github.com/streamlit/demo-uber-nyc-pickups), this is an example of how quickly an existing application can be wrapped in a HydraHeadAPP class and used in Hydralit.")
68
+
69
+
70
+ except Exception as e:
71
+ st.image(os.path.join(".","resources","failure.png"),width=100,)
72
+ st.error('An error has occurred, someone will be punished for your inconvenience, we humbly request you try again.')
73
+ st.error('Error details: {}'.format(e))
74
+
75
+
76
+
77
+
78
+
apps/load_app.py ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import hydralit_components as hc
3
+ import time
4
+ from hydralit import HydraHeadApp
5
+
6
+
7
+ class LoaderTestApp(HydraHeadApp):
8
+
9
+ def __init__(self, title = 'Loader Playground', delay=0, **kwargs):
10
+ self.__dict__.update(kwargs)
11
+ self.title = title
12
+ self.delay = delay
13
+
14
+ def run(self):
15
+
16
+ single_loader_list={
17
+ 'pacman':{'loader': hc.Loaders.pacman,'length': 0},
18
+ 'points_line':{'loader': hc.Loaders.points_line,'length': 0},
19
+ 'grid_points':{'loader': hc.Loaders.grid_points,'length': 0},
20
+ 'pulse_bars':{'loader': hc.Loaders.pulse_bars,'length': 0},
21
+ 'showcase_pretty':{'loader': hc.Loaders.showcase_pretty,'length': 0}
22
+ }
23
+
24
+ multi_loader_list={
25
+ 'standard_loaders': {'loader': hc.Loaders.standard_loaders,'length': 8},
26
+ 'pretty_loaders': {'loader': hc.Loaders.pretty_loaders,'length': 15}
27
+ }
28
+
29
+ s,c1,c2,c3 = st.columns([2,4,4,4])
30
+ loader_delay = st.slider('Loader Display Time (sec)', 2, 20, 5)
31
+ loader_mixer = s.checkbox('Multi-select Loaders')
32
+
33
+
34
+ if loader_mixer:
35
+ loader_list = multi_loader_list
36
+ loader_replicat = s.checkbox('Enable Loader Replication')
37
+ selected_loader = c1.selectbox('Select Loader',loader_list.keys())
38
+
39
+ if loader_replicat:
40
+ loader_index = c2.selectbox('Loader index',list(range(loader_list[selected_loader]['length'])))
41
+ loader_rep = c3.selectbox('Loader Replication',[1,2,3,4,5,6,7,8,9,10])
42
+ loader_index=[loader_index]*loader_rep
43
+ else:
44
+ loader_index = c2.multiselect('Loader indexes',list(range(loader_list[selected_loader]['length'])))
45
+
46
+ else:
47
+ loader_list = single_loader_list
48
+ loader_index = 0
49
+ selected_loader = c1.selectbox('Select Loader',loader_list.keys())
50
+
51
+
52
+ b,c, = st.columns([3,7])
53
+
54
+ if b.button('Unleash the Loader!'):
55
+ with hc.HyLoader('Now doing loading',loader_list[selected_loader]['loader'],index=loader_index):
56
+ time.sleep(loader_delay)
57
+
58
+ cex = c.expander('Show Code')
59
+
60
+ cex.code(
61
+ """
62
+ import hydralit_components as hc
63
+
64
+ single_loader_list={
65
+ 'pacman': hc.Loaders.pacman
66
+ 'points_line': hc.Loaders.points_line
67
+ 'grid_points': hc.Loaders.grid_points
68
+ 'pulse_bars': hc.Loaders.pulse_bars
69
+ 'showcase_pretty': hc.Loaders.showcase_pretty
70
+ }
71
+
72
+ multi_loader_list={
73
+ 'standard_loaders': hc.Loaders.standard_loaders,
74
+ 'pretty_loaders': hc.Loaders.pretty_loaders
75
+ }
76
+
77
+ # a dedicated single loader
78
+ with hc.HyLoader('Now doing loading',single_loader_list['pacman'],):
79
+ time.sleep(loader_delay)
80
+
81
+ # for 3 loaders from the standard loader group
82
+ with hc.HyLoader('Now doing loading',multi_loader_list['standard_loaders'],index=[3,0,5]):
83
+ time.sleep(loader_delay)
84
+
85
+ # for 1 (index=5) from the standard loader group
86
+ with hc.HyLoader('Now doing loading',multi_loader_list['standard_loaders'],index=5):
87
+ time.sleep(loader_delay)
88
+
89
+ # for 4 replications of the same loader (index=2) from the standard loader group
90
+ with hc.HyLoader('Now doing loading',multi_loader_list['standard_loaders'],index=[2,2,2,2]):
91
+ time.sleep(loader_delay)
92
+ """
93
+ )
apps/login_app.py ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ from typing import Dict
3
+ import streamlit as st
4
+ from hydralit import HydraHeadApp
5
+
6
+
7
+ class LoginApp(HydraHeadApp):
8
+ """
9
+ This is an example login application to be used to secure access within a HydraApp streamlit application.
10
+ This application implementation uses the allow_access session variable and uses the do_redirect method if the login check is successful.
11
+
12
+ """
13
+
14
+ def __init__(self, title = '', **kwargs):
15
+ self.__dict__.update(kwargs)
16
+ self.title = title
17
+
18
+
19
+ def run(self) -> None:
20
+ """
21
+ Application entry point.
22
+ """
23
+
24
+ st.markdown("<h1 style='text-align: center;'>Secure Hydralit Login</h1>", unsafe_allow_html=True)
25
+
26
+ c1,c2,c3, = st.columns([2,2,2])
27
+ c3.image("./resources/lock.png",width=100,)
28
+ c3.image("./resources/hydra.png",width=100,)
29
+
30
+ form_data = self._create_login_form(c2)
31
+
32
+ pretty_btn = """
33
+ <style>
34
+ div[class="row-widget stButton"] > button {
35
+ width: 100%;
36
+ }
37
+ </style>
38
+ <br><br>
39
+ """
40
+ c2.markdown(pretty_btn,unsafe_allow_html=True)
41
+
42
+ if form_data['submitted']:
43
+ self._do_login(form_data, c2)
44
+
45
+
46
+ def _create_login_form(self, parent_container) -> Dict:
47
+
48
+ login_form = parent_container.form(key="login_form")
49
+
50
+ form_state = {}
51
+ form_state['username'] = login_form.text_input('Username')
52
+ form_state['password'] = login_form.text_input('Password',type="password")
53
+ form_state['access_level'] = login_form.selectbox('Example Access Level',(1,2))
54
+ form_state['submitted'] = login_form.form_submit_button('Login')
55
+
56
+ parent_container.write("sample login -> joe & joe")
57
+
58
+ if parent_container.button('Guest Login',key='guestbtn'):
59
+ # set access level to a negative number to allow a kick to the unsecure_app set in the parent
60
+ self.set_access(1, 'guest')
61
+ self.do_redirect()
62
+
63
+ if parent_container.button('Sign Up',key='signupbtn'):
64
+ # set access level to a negative number to allow a kick to the unsecure_app set in the parent
65
+ self.set_access(-1, 'guest')
66
+
67
+ #Do the kick to the signup app
68
+ self.do_redirect()
69
+
70
+ return form_state
71
+
72
+
73
+ def _do_login(self, form_data, msg_container) -> None:
74
+
75
+ #access_level=0 Access denied!
76
+ access_level = self._check_login(form_data)
77
+
78
+ if access_level > 0:
79
+ msg_container.success(f"βœ”οΈ Login success")
80
+ with st.spinner("πŸ€“ now redirecting to application...."):
81
+ time.sleep(1)
82
+
83
+ #access control uses an int value to allow for levels of permission that can be set for each user, this can then be checked within each app seperately.
84
+ self.set_access(form_data['access_level'], form_data['username'])
85
+
86
+ #Do the kick to the home page
87
+ self.do_redirect()
88
+ else:
89
+ self.session_state.allow_access = 0
90
+ self.session_state.current_user = None
91
+
92
+ msg_container.error(f"❌ Login unsuccessful, πŸ˜• please check your username and password and try again.")
93
+
94
+
95
+ def _check_login(self, login_data) -> int:
96
+ #this method returns a value indicating the success of verifying the login details provided and the permission level, 1 for default access, 0 no access etc.
97
+
98
+ if login_data['username'] == 'joe' and login_data['password'] == 'joe':
99
+ return 1
100
+ else:
101
+ return 0
apps/myloading_app.py ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ import streamlit as st
3
+ from hydralit import HydraHeadApp
4
+ from hydralit_components import HyLoader, Loaders
5
+
6
+
7
+ class MyLoadingApp(HydraHeadApp):
8
+
9
+ def __init__(self, title = 'Loader', delay=0,loader=Loaders.standard_loaders, **kwargs):
10
+ self.__dict__.update(kwargs)
11
+ self.title = title
12
+ self.delay = delay
13
+ self._loader = loader
14
+
15
+ def run(self,app_target):
16
+
17
+ try:
18
+
19
+ se_loader_txt = """
20
+ <style>
21
+ #rcorners1 {
22
+ border-radius: 25px;
23
+ background: grey;
24
+ color: #00000;
25
+ alignment: center;
26
+ opacity: 0.95;
27
+ padding: 20px;
28
+ width: 1920px;
29
+ height: 400px;
30
+ z-index: 9998;
31
+ }
32
+ #banner {
33
+ color: white;
34
+ vertical-align: text-top;
35
+ text-align: center;
36
+ z-index: 9999;
37
+ }
38
+ </style>
39
+ <div id="rcorners1">
40
+ <h1 id="banner">Now loading Sequency Denoising</h1>
41
+ <br>
42
+ </div>
43
+ """
44
+ app_title = ''
45
+ if hasattr(app_target,'title'):
46
+ app_title = app_target.title
47
+
48
+ if app_title == 'Sequency Denoising':
49
+ with HyLoader(se_loader_txt, loader_name=Loaders.pacman):
50
+ time.sleep(int(self.delay))
51
+ app_target.run()
52
+
53
+ elif app_title == 'Loader Playground':
54
+ app_target.run()
55
+ else:
56
+ with HyLoader("✨Now loading {}".format(app_title), loader_name=self._loader,index=[3,0,5]):
57
+ time.sleep(int(self.delay))
58
+ app_target.run()
59
+
60
+
61
+
62
+ except Exception as e:
63
+ st.image("./resources/failure.png",width=100,)
64
+ st.error('An error has occurred, someone will be punished for your inconvenience, we humbly request you try again.')
65
+ st.error('Error details: {}'.format(e))
66
+
apps/signup.py ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ import os
3
+ from typing import Dict
4
+ import streamlit as st
5
+ from hydralit import HydraHeadApp
6
+
7
+
8
+ class SignUpApp(HydraHeadApp):
9
+ """
10
+ This is an example signup application to be used to secure access within a HydraApp streamlit application.
11
+
12
+ This application is an example of allowing an application to run from the login without requiring authentication.
13
+
14
+ """
15
+
16
+ def __init__(self, title = '', **kwargs):
17
+ self.__dict__.update(kwargs)
18
+ self.title = title
19
+
20
+
21
+ def run(self) -> None:
22
+ """
23
+ Application entry point.
24
+
25
+ """
26
+
27
+ st.markdown("<h1 style='text-align: center;'>Secure Hydralit Signup</h1>", unsafe_allow_html=True)
28
+
29
+ c1,c2,c3 = st.columns([2,2,2])
30
+ c3.image("./resources/lock.png",width=100,)
31
+ c3.image("./resources/hydra.png",width=100,)
32
+
33
+ pretty_btn = """
34
+ <style>
35
+ div[class="row-widget stButton"] > button {
36
+ width: 100%;
37
+ }
38
+ </style>
39
+ <br><br>
40
+ """
41
+ c2.markdown(pretty_btn,unsafe_allow_html=True)
42
+
43
+ if 'MSG' in os.environ.keys():
44
+ st.info(os.environ['MSG'])
45
+
46
+ form_data = self._create_signup_form(c2)
47
+
48
+ pretty_btn = """
49
+ <style>
50
+ div[class="row-widget stButton"] > button {
51
+ width: 100%;
52
+ }
53
+ </style>
54
+ <br><br>
55
+ """
56
+ c2.markdown(pretty_btn,unsafe_allow_html=True)
57
+
58
+
59
+
60
+ if form_data['submitted']:
61
+ self._do_signup(form_data, c2)
62
+
63
+
64
+ def _create_signup_form(self, parent_container) -> Dict:
65
+
66
+ login_form = parent_container.form(key="login_form")
67
+
68
+ form_state = {}
69
+ form_state['username'] = login_form.text_input('Username')
70
+ form_state['password'] = login_form.text_input('Password',type="password")
71
+ form_state['password2'] = login_form.text_input('Confirm Password',type="password")
72
+ form_state['access_level'] = login_form.selectbox('Example Access Level',(1,2))
73
+ form_state['submitted'] = login_form.form_submit_button('Sign Up')
74
+
75
+ if parent_container.button('Login',key='loginbtn'):
76
+ # set access level to a negative number to allow a kick to the unsecure_app set in the parent
77
+ self.set_access(0, None)
78
+
79
+ #Do the kick to the signup app
80
+ self.do_redirect()
81
+
82
+ return form_state
83
+
84
+ def _do_signup(self, form_data, msg_container) -> None:
85
+ if form_data['submitted'] and (form_data['password'] != form_data['password2']):
86
+ st.error('Passwords do not match, please try again.')
87
+ else:
88
+ with st.spinner("πŸ€“ now redirecting to login...."):
89
+ self._save_signup(form_data)
90
+ time.sleep(2)
91
+
92
+ #access control uses an int value to allow for levels of permission that can be set for each user, this can then be checked within each app seperately.
93
+ self.set_access(0, None)
94
+
95
+ #Do the kick back to the login screen
96
+ self.do_redirect()
97
+
98
+ def _save_signup(self, signup_data):
99
+ #get the user details from the form and save somehwere
100
+
101
+ #signup_data
102
+ # this is the data submitted
103
+
104
+ #just show the data we captured
105
+ what_we_got = f"""
106
+ captured signup details: \n
107
+ username: {signup_data['username']} \n
108
+ password: {signup_data['password']} \n
109
+ access level: {signup_data['access_level']} \n
110
+ """
111
+
112
+ st.write(what_we_got)
113
+
apps/solar_mach.py ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import datetime
2
+ import io
3
+ from hydralit import HydraHeadApp
4
+
5
+ import astropy.units as u
6
+ import pandas as pd
7
+ import streamlit as st
8
+ from astropy.coordinates import SkyCoord
9
+ from sunpy.coordinates import frames
10
+
11
+ from apps.extras.backmapping import *
12
+ import hydralit_components as hc
13
+
14
+
15
+ class SolarMach(HydraHeadApp):
16
+
17
+ def __init__(self, title = '', **kwargs):
18
+ self.__dict__.update(kwargs)
19
+ self.title = title
20
+
21
+ def run(self):
22
+
23
+ st.title('Solar-MACH')
24
+
25
+ st.subheader('Source for this great app is from the Streamlit gallery [Solar-MACH](https://github.com/jgieseler/Solar-MACH). An example of how easy it is to convert an existing application and use within a Hydralit multi-page application, see the secret saurce [here] (https://github.com/TangleSpace/hydralit).')
26
+ st.markdown('<br><br>',unsafe_allow_html=True)
27
+ st.markdown('## Multi-spacecraft longitudinal configuration plotter')
28
+
29
+ # provide date and time
30
+ with st.sidebar.container():
31
+ d = st.sidebar.date_input("Select date", datetime.date.today()-datetime.timedelta(days = 2))
32
+ t = st.sidebar.time_input('Select time', datetime.time(1, 30))
33
+ date = datetime.datetime.combine(d, t).strftime("%Y-%m-%d %H:%M:%S")
34
+
35
+ # plotting settings
36
+ with st.sidebar.container():
37
+ st.sidebar.subheader('Plot options:')
38
+ plot_spirals = st.sidebar.checkbox('Parker spiral for each body', value=True)
39
+ plot_sun_body_line = st.sidebar.checkbox('Straight line from Sun to body', value=True)
40
+ show_earth_centered_coord = st.sidebar.checkbox('Add Earth-aligned coord. system', value=False)
41
+ transparent = st.sidebar.checkbox('Transparent background', value=False)
42
+
43
+ plot_reference = st.sidebar.checkbox('Plot reference (e.g. flare)', value=True)
44
+
45
+ with st.sidebar.expander("Reference coordinates (e.g. flare)", expanded=plot_reference):
46
+ reference_sys = st.radio('Coordinate system:', ['Carrington', 'Stonyhurst'], index=0)
47
+ if reference_sys == 'Carrington':
48
+ reference_long = st.slider('Longitude:', 0, 360, 20)
49
+ reference_lat = st.slider('Latitude:', -90, 90, 0)
50
+ if reference_sys == 'Stonyhurst':
51
+ reference_long = st.slider('Longitude:', -180, 180, 20)
52
+ reference_lat = st.slider('Latitude:', -90, 90, 0)
53
+ # convert Stonyhurst coordinates to Carrington for further use:
54
+ coord = SkyCoord(reference_long*u.deg, reference_lat*u.deg, frame=frames.HeliographicStonyhurst, obstime=date)
55
+ coord = coord.transform_to(frames.HeliographicCarrington(observer='Sun'))
56
+ reference_long = coord.lon.value
57
+ reference_lat = coord.lat.value
58
+ import math
59
+ reference_vsw = int(float(st.text_input('Solar wind speed for reference', 400)))
60
+ if plot_reference is False:
61
+ reference_long = None
62
+ reference_lat = None
63
+
64
+ st.sidebar.subheader('Choose bodies/spacecraft and measured solar wind speeds')
65
+ with st.sidebar.container():
66
+ full_body_list = \
67
+ st.sidebar.text_area('Bodies/spacecraft (scroll down for example list)',
68
+ 'STEREO A, Earth, BepiColombo, PSP, Solar Orbiter, Mars',
69
+ height=50)
70
+ vsw_list = \
71
+ st.sidebar.text_area('Solar wind speed per body/SC (mind the order!)', '400, 400, 400, 400, 400, 400',
72
+ height=50)
73
+ body_list = full_body_list.split(',')
74
+ vsw_list = vsw_list.split(',')
75
+ body_list = [body_list[i].strip() for i in range(len(body_list))]
76
+ wrong_vsw = False
77
+ try:
78
+ vsw_list = [int(vsw_list[i].strip()) for i in range(len(vsw_list))]
79
+ except ValueError:
80
+ wrong_vsw = True
81
+
82
+ all_bodies = print_body_list()
83
+ # ugly workaround to not show the index in the table: replace them with empty strings
84
+ all_bodies.reset_index(inplace=True)
85
+ all_bodies.index = [""] * len(all_bodies)
86
+ st.sidebar.table(all_bodies['Key'])
87
+
88
+ st.sidebar.markdown('[Complete list of available bodies](https://ssd.jpl.nasa.gov/horizons.cgi?s_target=1#top)')
89
+
90
+ if wrong_vsw:
91
+ st.error('ERROR: There is something wrong in the solar wind speed list! Maybe some missing or wrong comma?')
92
+ st.stop()
93
+
94
+
95
+ if len(body_list) == len(vsw_list):
96
+ # initialize the bodies
97
+ c = HeliosphericConstellation(date, body_list, vsw_list, reference_long,
98
+ reference_lat)
99
+
100
+ # make the longitudinal constellation plot
101
+ plot_file = 'Solar-MACH_'+datetime.datetime.combine(d, t).strftime("%Y-%m-%d_%H-%M-%S")+'.png'
102
+
103
+ c.plot(
104
+ plot_spirals=plot_spirals, # plot Parker spirals for each body
105
+ plot_sun_body_line=plot_sun_body_line, # plot straight line between Sun and body
106
+ show_earth_centered_coord=show_earth_centered_coord, # display Earth-aligned coordinate system
107
+ reference_vsw=reference_vsw, # define solar wind speed at reference
108
+ transparent = transparent,
109
+ # outfile=plot_file # output file (optional)
110
+ )
111
+
112
+ # download plot
113
+ filename = 'Solar-MACH_'+datetime.datetime.combine(d, t).strftime("%Y-%m-%d_%H-%M-%S")
114
+ plot2 = io.BytesIO()
115
+ plt.savefig(plot2, format='png', bbox_inches="tight")
116
+ # plot3 = base64.b64encode(plot2.getvalue()).decode("utf-8").replace("\n", "")
117
+ # st.markdown(f'<a href="data:file/png;base64,{plot3}" download="{plot_file}" target="_blank">Download figure as .png file</a>', unsafe_allow_html=True)
118
+ download_button_str = self.download_button(plot2.getvalue(), filename+'.png', f'Download figure as .png file', pickle_it=False)
119
+ #st.markdown(download_button_str, unsafe_allow_html=True)
120
+
121
+ # display coordinates table
122
+ df = c.coord_table
123
+ df.index = df['Spacecraft/Body']
124
+ df = df.drop(columns=['Spacecraft/Body'])
125
+ df = df.round(0)
126
+ df = df.rename(columns=
127
+ {"Spacecraft/Body": "Spacecraft / body",
128
+ "Carrington Longitude (Β°)": "Carrington longitude",
129
+ "Latitude (Β°)": "Carrington latitude",
130
+ "Heliocentric Distance (AU)": "Heliocent. distance",
131
+ "Longitudinal separation to Earth's longitude": "Longitud. separation to Earth longitude",
132
+ "Latitudinal separation to Earth's latitude": "Latitud. separation to Earth latitude",
133
+ "Vsw": "Solar wind speed",
134
+ "Magnetic footpoint longitude (Carrington)": "Magnetic footpoint Carrington longitude",
135
+ "Longitudinal separation between body and reference_long": "Longitud. separation bw. body & reference",
136
+ "Longitudinal separation between body's mangetic footpoint and reference_long": "Longitud. separation bw. body's magnetic footpoint & reference",
137
+ "Latitudinal separation between body and reference_lat": "Latitudinal separation bw. body & reference"})
138
+ st.table(df.T)
139
+
140
+ # download coordinates
141
+ # filename = 'Solar-MACH_'+datetime.datetime.combine(d, t).strftime("%Y-%m-%d_%H-%M-%S")
142
+ # csv = c.coord_table.to_csv().encode()
143
+ # b64 = base64.b64encode(csv).decode()
144
+ # st.markdown(f'<a href="data:file/csv;base64,{b64}" download="{filename}.csv" target="_blank">Download table as .csv file</a>', unsafe_allow_html=True)
145
+ download_button_str = self.download_button(c.coord_table, filename+'.csv', f'Download table as .csv file', pickle_it=False)
146
+ #st.markdown(download_button_str, unsafe_allow_html=True)
147
+ else:
148
+ st.error(f"ERROR: Number of elements in the bodies/spacecraft list \
149
+ ({len(body_list)}) and solar wind speed list ({len(vsw_list)}) \
150
+ don't match! Please verify that for each body there is a solar \
151
+ wind speed provided!")
152
+
153
+ # footer
154
+ st.markdown("""---""")
155
+ st.markdown('The *Solar MAgnetic Connection Haus* (Solar-MACH) tool is a \
156
+ multi-spacecraft longitudinal configuration plotter. It was \
157
+ originally developed at the University of Kiel, Germany, and further \
158
+ discussed within the [ESA Heliophysics Archives USer (HAUS)]\
159
+ (https://www.cosmos.esa.int/web/esdc/archives-user-groups/heliophysics) \
160
+ group. It is now opened to everyone ([original code]\
161
+ (https://github.com/esdc-esac-esa-int/Solar-MACH)).')
162
+
163
+ st.markdown('[Forked and modified](https://github.com/jgieseler/Solar-MACH) by \
164
+ [J. Gieseler](https://jgieseler.github.io) (University of Turku, Finland). \
165
+ [**Get in contact**](mailto:jan.gieseler@utu.fi?subject=Solar-MACH).')
166
+
167
+ col1, col2 = st.columns((5,1))
168
+ col1.markdown("The development of the online tool has received funding from the \
169
+ European Union's Horizon 2020 research and innovation programme \
170
+ under grant agreement No 101004159 (SERPENTINE).")
171
+ col2.markdown('[<img src="https://serpentine-h2020.eu/wp-content/uploads/2021/02/SERPENTINE_logo_new.png" \
172
+ height="80">](https://serpentine-h2020.eu)', unsafe_allow_html=True)
173
+
174
+ st.markdown('Powered by: \
175
+ [<img src="https://matplotlib.org/stable/_static/logo2_compressed.svg" height="25">](https://matplotlib.org) \
176
+ [<img src="https://streamlit.io/images/brand/streamlit-logo-secondary-colormark-darktext.svg" height="30">](https://streamlit.io) \
177
+ [<img src="https://raw.githubusercontent.com/sunpy/sunpy-logo/master/generated/sunpy_logo_landscape.svg" height="30">](https://sunpy.org)', \
178
+ unsafe_allow_html=True)
apps/spacy_nlp.py ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import spacy_streamlit
2
+ from pathlib import Path
3
+ import streamlit as st
4
+ import srsly
5
+ import os
6
+ import importlib
7
+
8
+ from hydralit import HydraHeadApp
9
+
10
+ class SpacyNLP(HydraHeadApp):
11
+
12
+ def __init__(self, title = '', **kwargs):
13
+ self.__dict__.update(kwargs)
14
+ self.title = title
15
+
16
+ def run(self):
17
+
18
+ #st.experimental_set_query_params(selected=self.title)
19
+
20
+ MODELS = srsly.read_json(os.path.join(Path(__file__).parent,"extras","models.json"))
21
+ DEFAULT_MODEL = "en_core_web_sm"
22
+ DEFAULT_TEXT = "David Bowie moved to the US in 1974, initially staying in New York City before settling in Los Angeles."
23
+ DESCRIPTION = """**Explore trained [spaCy v3.0](https://nightly.spacy.io) pipelines**"""
24
+
25
+ def get_default_text(nlp):
26
+ # Check if spaCy has built-in example texts for the language
27
+ try:
28
+ examples = importlib.import_module(f".lang.{nlp.lang}.examples", "spacy")
29
+ return examples.sentences[0]
30
+ except (ModuleNotFoundError, ImportError):
31
+ return ""
32
+
33
+ st.subheader('Source for this great app is from the Streamlit gallery [NLP with spaCy](https://github.com/ines/spacy-streamlit-demo). An example of how easy it is to convert an existing application and use within a Hydralit multi-page application, see the secret saurce [here] (https://github.com/TangleSpace/hydralit).')
34
+ st.markdown('<br><br>',unsafe_allow_html=True)
35
+
36
+ st.info(r"Yes, this application will show an error if you don't have the 'en_core_web_sm' Spacy model installed, this was left to show that if an app crashes, it won't affect the HydraApp or the other HydraHeadApps, this app will crash and burn on it's own. If you want to fix the error, just install the missing model with [**python -m spacy download en_core_web_sm**](https://spacy.io/usage)")
37
+ spacy_streamlit.visualize(
38
+ MODELS,
39
+ default_model=DEFAULT_MODEL,
40
+ visualizers=["parser", "ner", "similarity", "tokens"],
41
+ show_visualizer_select=True,
42
+ sidebar_description=DESCRIPTION,
43
+ get_default_text=get_default_text
44
+ )
apps/uber_app.py ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2018-2019 Streamlit Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import streamlit as st
16
+ import pandas as pd
17
+ import numpy as np
18
+ import altair as alt
19
+ import pydeck as pdk
20
+ from hydralit import HydraHeadApp
21
+
22
+
23
+ class UberNYC(HydraHeadApp):
24
+
25
+ def __init__(self, title = '', **kwargs):
26
+ self.__dict__.update(kwargs)
27
+ self.title = title
28
+
29
+ def run(self):
30
+
31
+ #st.experimental_set_query_params(selected=self.title)
32
+ print(self.title)
33
+
34
+ # LOADING DATA
35
+ DATE_TIME = "date/time"
36
+ DATA_URL = (
37
+ "http://s3-us-west-2.amazonaws.com/streamlit-demo-data/uber-raw-data-sep14.csv.gz"
38
+ )
39
+
40
+ @st.cache(persist=True)
41
+ def load_data(nrows):
42
+ data = pd.read_csv(DATA_URL, nrows=nrows)
43
+ lowercase = lambda x: str(x).lower()
44
+ data.rename(lowercase, axis="columns", inplace=True)
45
+ data[DATE_TIME] = pd.to_datetime(data[DATE_TIME])
46
+ return data
47
+
48
+ data = load_data(100000)
49
+
50
+ # CREATING FUNCTION FOR MAPS
51
+
52
+ def map(data, lat, lon, zoom):
53
+ st.write(pdk.Deck(
54
+ map_style="mapbox://styles/mapbox/light-v9",
55
+ initial_view_state={
56
+ "latitude": lat,
57
+ "longitude": lon,
58
+ "zoom": zoom,
59
+ "pitch": 50,
60
+ },
61
+ layers=[
62
+ pdk.Layer(
63
+ "HexagonLayer",
64
+ data=data,
65
+ get_position=["lon", "lat"],
66
+ radius=100,
67
+ elevation_scale=4,
68
+ elevation_range=[0, 1000],
69
+ pickable=True,
70
+ extruded=True,
71
+ ),
72
+ ]
73
+ ))
74
+
75
+ st.subheader('Source for this great app is from the Streamlit gallery [NYC Uber Ridesharing Data](https://github.com/streamlit/demo-uber-nyc-pickups). An example of how easy it is to convert an existing application and use within a Hydralit multi-page application, see the secret saurce [here] (https://github.com/TangleSpace/hydralit).')
76
+ st.markdown('<br><br>',unsafe_allow_html=True)
77
+
78
+ # LAYING OUT THE TOP SECTION OF THE APP
79
+ row1_1, row1_2 = st.columns((2,3))
80
+
81
+ with row1_1:
82
+ st.title("NYC Uber Ridesharing Data")
83
+
84
+ hour_selected = st.slider("Select hour of pickup", 0, 23)
85
+
86
+ with row1_2:
87
+ st.write(
88
+ """
89
+ ##
90
+ Examining how Uber pickups vary over time in New York City's and at its major regional airports.
91
+ By sliding the slider on the left you can view different slices of time and explore different transportation trends.
92
+ """)
93
+
94
+ # FILTERING DATA BY HOUR SELECTED
95
+ data = data[data[DATE_TIME].dt.hour == hour_selected]
96
+
97
+ # LAYING OUT THE MIDDLE SECTION OF THE APP WITH THE MAPS
98
+ row2_1, row2_2, row2_3, row2_4 = st.columns((2,1,1,1))
99
+
100
+ # SETTING THE ZOOM LOCATIONS FOR THE AIRPORTS
101
+ la_guardia= [40.7900, -73.8700]
102
+ jfk = [40.6650, -73.7821]
103
+ newark = [40.7090, -74.1805]
104
+ zoom_level = 12
105
+ midpoint = (np.average(data["lat"]), np.average(data["lon"]))
106
+
107
+ with row2_1:
108
+ st.write("**All New York City from %i:00 and %i:00**" % (hour_selected, (hour_selected + 1) % 24))
109
+ map(data, midpoint[0], midpoint[1], 11)
110
+
111
+ with row2_2:
112
+ st.write("**La Guardia Airport**")
113
+ map(data, la_guardia[0],la_guardia[1], zoom_level)
114
+
115
+ with row2_3:
116
+ st.write("**JFK Airport**")
117
+ map(data, jfk[0],jfk[1], zoom_level)
118
+
119
+ with row2_4:
120
+ st.write("**Newark Airport**")
121
+ map(data, newark[0],newark[1], zoom_level)
122
+
123
+ # FILTERING DATA FOR THE HISTOGRAM
124
+ filtered = data[
125
+ (data[DATE_TIME].dt.hour >= hour_selected) & (data[DATE_TIME].dt.hour < (hour_selected + 1))
126
+ ]
127
+
128
+ hist = np.histogram(filtered[DATE_TIME].dt.minute, bins=60, range=(0, 60))[0]
129
+
130
+ chart_data = pd.DataFrame({"minute": range(60), "pickups": hist})
131
+
132
+ # LAYING OUT THE HISTOGRAM SECTION
133
+
134
+ st.write("")
135
+
136
+ st.write("**Breakdown of rides per minute between %i:00 and %i:00**" % (hour_selected, (hour_selected + 1) % 24))
137
+
138
+ st.altair_chart(alt.Chart(chart_data)
139
+ .mark_area(
140
+ interpolate='step-after',
141
+ ).encode(
142
+ x=alt.X("minute:Q", scale=alt.Scale(nice=False)),
143
+ y=alt.Y("pickups:Q"),
144
+ tooltip=['minute', 'pickups']
145
+ ).configure_mark(
146
+ opacity=0.5,
147
+ color='red'
148
+ ), use_container_width=True)
apps/walsh_app.py ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import streamlit as st
3
+ from hydralit import HydraHeadApp
4
+ import matplotlib.pyplot as plt
5
+ import numpy as np
6
+ import pandas as pd
7
+ from hotstepper import Steps,Step
8
+ import hotstepper as hs
9
+ from itertools import chain
10
+ from hotstepper import Sequency
11
+
12
+
13
+ SIG_FIGURE_FMT = '{:,.2f}'
14
+
15
+ class WalshApp(HydraHeadApp):
16
+
17
+
18
+ def __init__(self, title = '', **kwargs):
19
+ self.__dict__.update(kwargs)
20
+ self.title = title
21
+
22
+
23
+ def run(self):
24
+
25
+ try:
26
+ st.title('Sequency Denoising')
27
+ st.subheader('Source for this quick tutorial on using Sequency methods for denoising step change data can be found in the [Hotstepper documentation](https://hotstepper.readthedocs.io/notebooks/sequency_quickstart.html). An example of how easy it is to convert an existing application and use within a Hydralit multi-page application, see the secret saurce [here] (https://github.com/TangleSpace/hydralit).')
28
+ st.markdown('<br><br>',unsafe_allow_html=True)
29
+
30
+ df_vq_samp = pd.read_csv(r'https://raw.githubusercontent.com/TangleSpace/hotstepper-data/master/data/vessel_queue.csv',parse_dates=['enter','leave'],dayfirst=True)
31
+ self.download_button(df_vq_samp,'data.csv','Download Example Data')
32
+
33
+ st.write(
34
+ """
35
+ Another typical use case of Fourier transforms is to remove high frequency noise from a single by decomposing it into constituent frequency components and setting frequencies below a threshold value to zero. \
36
+ With Sequency analysis, we have a similar functionality, except since we have step data and we are wanting to retain the nature of the step data (as steps) instead of just smoothing away the details, \
37
+ we can use the denoise method of the Sequency module to remove the higher sequency number components. An explicit example is shown below, here for now, we pass in the direct steps data for denoising, \
38
+ apply a strength parameter to determine how many of the high sequency components are set to zero and then we construct a new Steps object.
39
+ """
40
+ )
41
+
42
+ st.code(
43
+ """
44
+ denoise_step_changes_strong = seq.denoise(rand_steps.step_changes(),denoise_strength=0.7,denoise_mode='range')
45
+ denoise_step_changes = seq.denoise(rand_steps.step_changes(),denoise_strength=0.2)
46
+
47
+ rand_steps_denoise_strong = Steps().add_direct(data_start=rand_steps.step_keys(),data_weight = denoise_step_changes_strong)
48
+ rand_steps_denoise = Steps().add_direct(data_start=rand_steps.step_keys(),data_weight = denoise_step_changes)
49
+
50
+ ax = rand_steps.plot(label='Original Data')
51
+ rand_steps_denoise.plot(ax=ax,color='g',linewidth=2,label='Light Denoise');
52
+ rand_steps_denoise_strong.plot(ax=ax,color='r',linewidth=2,linestyle='-',label='Strong Denoise')
53
+ ax.legend();
54
+ """
55
+ )
56
+
57
+ denoise_power_strong_select = st.sidebar.slider('Strong Denoise Strength',value=0.7,min_value=0.01,max_value=1.0,step=0.01)
58
+ denoise_power_light_select = st.sidebar.slider('Light Denoise Strength',value=0.2,min_value=0.01,max_value=1.0,step=0.01)
59
+ denoise_mode_select = st.sidebar.radio('Denoise Mode',('range','value'))
60
+
61
+
62
+ seq = Sequency()
63
+ #Create a sequence of steps that we can analyse
64
+ steps_changes = np.random.randint(-10,12,100)
65
+ rand_steps = Steps().add_direct(data_start=list(range(1,len(steps_changes))),data_weight = steps_changes)
66
+
67
+ denoise_step_changes_strong = seq.denoise(rand_steps.step_changes(),denoise_strength=denoise_power_strong_select,denoise_mode=denoise_mode_select)
68
+ denoise_step_changes = seq.denoise(rand_steps.step_changes(),denoise_strength=denoise_power_light_select,denoise_mode=denoise_mode_select)
69
+
70
+ rand_steps_denoise_strong = Steps().add_direct(data_start=rand_steps.step_keys(),data_weight = denoise_step_changes_strong)
71
+ rand_steps_denoise = Steps().add_direct(data_start=rand_steps.step_keys(),data_weight = denoise_step_changes)
72
+
73
+ ax = rand_steps.plot(label='Original Data')
74
+ rand_steps_denoise.plot(ax=ax,color='g',linewidth=2,label='Light Denoise')
75
+ rand_steps_denoise_strong.plot(ax=ax,color='r',linewidth=2,linestyle='-',label='Strong Denoise')
76
+ ax.legend()
77
+
78
+ st.pyplot(ax.get_figure(),clear_figure=True)
79
+
80
+
81
+ st.write(
82
+ """
83
+ As another quick example, we can apply the same technique to one of the HotStepper sample datasets, for this tutorial, we’ll only look at the first two months of data in order to better highlight what the sequency denoising can do to help better show the trend or typical step behaviour of the data.
84
+ """
85
+ )
86
+
87
+ st.code(
88
+ """
89
+ df_vq_samp = pd.read_csv(r'https://raw.githubusercontent.com/TangleSpace/hotstepper-data/master/data/vessel_queue.csv',parse_dates=['enter','leave'],dayfirst=True)
90
+
91
+ vq_samp = Steps.read_dataframe(df_vq_samp,start='enter',end='leave')
92
+ vq_clip = vq_samp.clip(ubound=pd.Timestamp(2020,3,1))
93
+
94
+ dn = seq.denoise(vq_clip.step_changes(),denoise_mode='range')
95
+ vq_clip_dn = Steps().add_direct(data_start=vq_clip.step_keys(convert_keys=True),data_weight=dn)
96
+
97
+ ax = vq_clip.plot(label='Original Data',figsize=(14,6))
98
+ vq_clip_dn.plot(ax=ax,linewidth=3,label='Sequency Denoise')
99
+ ax.legend()
100
+ """
101
+ )
102
+
103
+ vq_samp = Steps.read_dataframe(df_vq_samp,start='enter',end='leave')
104
+ vq_clip = vq_samp.clip(ubound=pd.Timestamp(2020,3,1))
105
+
106
+
107
+ dn_strong = seq.denoise(vq_clip.step_changes(),denoise_strength=denoise_power_strong_select,denoise_mode=denoise_mode_select)
108
+ dn_light = seq.denoise(vq_clip.step_changes(),denoise_strength=denoise_power_light_select,denoise_mode=denoise_mode_select)
109
+
110
+ vq_clip_dn_strong = Steps().add_direct(data_start=vq_clip.step_keys(convert_keys=True),data_weight=dn_strong)
111
+ vq_clip_dn_light = Steps().add_direct(data_start=vq_clip.step_keys(convert_keys=True),data_weight=dn_light)
112
+
113
+ ax = vq_clip.plot(label='Original Data',figsize=(14,6))
114
+ vq_clip_dn_strong.plot(ax=ax,linewidth=1.5,label='Strong Sequency Denoise')
115
+ vq_clip_dn_light.plot(ax=ax,linewidth=1.5,label='Light Sequency Denoise')
116
+ ax.legend()
117
+
118
+ st.pyplot(ax.get_figure(),clear_figure=True)
119
+
120
+ st.write(
121
+ """
122
+ As the last item, we can take a look at the sequency spectrum for the vessel queue data. This dataset has a large number of changes and therefore the sequency range goes quite high, however it does show a number of peaks that are significantly larger than the others, indicating a number of distinct and repeating step change patterns within the data over this period.
123
+ """
124
+ )
125
+
126
+ st.code(
127
+ """
128
+ fig, (ax,ax2,ax3) = plt.subplots(nrows=3,figsize=(12,8))
129
+ fig.tight_layout(h_pad=4)
130
+
131
+ # Sequency object to use for analysis
132
+ vq_clip_seq = Sequency()
133
+ n,sp,l = vq_clip_seq.sequency_spectrum(vq_clip.step_changes())
134
+
135
+
136
+ ax.set_title('Step Change Sequency Spectrum')
137
+ ax.set_xlabel('Sequency Number')
138
+ ax.set_ylabel('Amplitude')
139
+ ax.stem(n,sp)
140
+
141
+ # number of data points, needed to create the sampling frequency
142
+ no_points = vq_clip.step_changes().shape[0]
143
+
144
+ fr,fsp = vq_clip_seq.frequency_spectrum(vq_clip.step_changes(),2*np.pi*no_points)
145
+
146
+ ax2.set_title('Step Change Frequency Spectrum')
147
+ ax2.set_xlabel('Frequency')
148
+ ax2.set_ylabel('Amplitude')
149
+ ax2.stem(fr,fsp)
150
+
151
+ # FFT the steps values instead of the delta changes to see the difference in the spectrum.
152
+ frv,fspv = vq_clip_seq.frequency_spectrum(vq_clip.step_values(),2*np.pi*no_points)
153
+
154
+ ax3.set_title('Steps Value Frequency Spectrum')
155
+ ax3.set_xlabel('Frequency')
156
+ ax3.set_ylabel('Amplitude')
157
+ ax3.stem(frv[1:],fspv[1:]);
158
+ """
159
+ )
160
+
161
+
162
+ fig, (ax,ax2,ax3) = plt.subplots(nrows=3,figsize=(12,8))
163
+ fig.tight_layout(h_pad=4)
164
+
165
+ # Sequency object to use for analysis
166
+ vq_clip_seq = Sequency()
167
+ n,sp,l = vq_clip_seq.sequency_spectrum(vq_clip.step_changes())
168
+
169
+
170
+ ax.set_title('Step Change Sequency Spectrum')
171
+ ax.set_xlabel('Sequency Number')
172
+ ax.set_ylabel('Amplitude')
173
+ ax.stem(n,sp)
174
+
175
+ # number of data points, needed to create the sampling frequency
176
+ no_points = vq_clip.step_changes().shape[0]
177
+
178
+ fr,fsp = vq_clip_seq.frequency_spectrum(vq_clip.step_changes(),2*np.pi*no_points)
179
+
180
+ ax2.set_title('Step Change Frequency Spectrum')
181
+ ax2.set_xlabel('Frequency')
182
+ ax2.set_ylabel('Amplitude')
183
+ ax2.stem(fr,fsp)
184
+
185
+ # FFT the steps values instead of the delta changes to see the difference in the spectrum.
186
+ frv,fspv = vq_clip_seq.frequency_spectrum(vq_clip.step_values(),2*np.pi*no_points)
187
+
188
+ ax3.set_title('Steps Value Frequency Spectrum')
189
+ ax3.set_xlabel('Frequency')
190
+ ax3.set_ylabel('Amplitude')
191
+ ax3.stem(frv[1:],fspv[1:])
192
+
193
+ st.pyplot(fig,clear_figure=True)
194
+
195
+
196
+ except Exception as e:
197
+ st.image("./resources/failure.png",width=100,)
198
+ st.error('An error has occurred, someone will be punished for your inconvenience, we humbly request you try again.')
199
+ st.error('Error details: {}'.format(e))
200
+
apps/walsh_app_secure.py ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import streamlit as st
3
+ from hydralit import HydraHeadApp
4
+ import matplotlib.pyplot as plt
5
+ import numpy as np
6
+ import pandas as pd
7
+ from hotstepper import Steps,Step
8
+ import hotstepper as hs
9
+ from hotstepper import Sequency
10
+
11
+
12
+ SIG_FIGURE_FMT = '{:,.2f}'
13
+
14
+ class WalshAppSecure(HydraHeadApp):
15
+
16
+
17
+ def __init__(self, title = '', **kwargs):
18
+ self.__dict__.update(kwargs)
19
+ self.title = title
20
+
21
+
22
+ def run(self):
23
+
24
+ try:
25
+ access_level,username = self.check_access()
26
+
27
+ if access_level > 1:
28
+
29
+ st.title('Sequency Denoising')
30
+ st.subheader('Source for this quick tutorial on using Sequency methods for denoising step change data can be found in the [Hotstepper documentation](https://hotstepper.readthedocs.io/notebooks/sequency_quickstart.html). An example of how easy it is to convert an existing application and use within a Hydralit multi-page application, see the secret saurce [here] (https://github.com/TangleSpace/hydralit).')
31
+ st.markdown('<br><br>',unsafe_allow_html=True)
32
+
33
+ df_vq_samp = pd.read_csv(r'https://raw.githubusercontent.com/TangleSpace/hotstepper-data/master/data/vessel_queue.csv',parse_dates=['enter','leave'],dayfirst=True)
34
+ self.download_button(df_vq_samp,'data.csv','Download Example Data')
35
+
36
+ st.write(
37
+ """
38
+ Another typical use case of Fourier transforms is to remove high frequency noise from a single by decomposing it into constituent frequency components and setting frequencies below a threshold value to zero. \
39
+ With Sequency analysis, we have a similar functionality, except since we have step data and we are wanting to retain the nature of the step data (as steps) instead of just smoothing away the details, \
40
+ we can use the denoise method of the Sequency module to remove the higher sequency number components. An explicit example is shown below, here for now, we pass in the direct steps data for denoising, \
41
+ apply a strength parameter to determine how many of the high sequency components are set to zero and then we construct a new Steps object.
42
+ """
43
+ )
44
+
45
+ st.code(
46
+ """
47
+ denoise_step_changes_strong = seq.denoise(rand_steps.step_changes(),denoise_strength=0.7,denoise_mode='range')
48
+ denoise_step_changes = seq.denoise(rand_steps.step_changes(),denoise_strength=0.2)
49
+
50
+ rand_steps_denoise_strong = Steps().add_direct(data_start=rand_steps.step_keys(),data_weight = denoise_step_changes_strong)
51
+ rand_steps_denoise = Steps().add_direct(data_start=rand_steps.step_keys(),data_weight = denoise_step_changes)
52
+
53
+ ax = rand_steps.plot(label='Original Data')
54
+ rand_steps_denoise.plot(ax=ax,color='g',linewidth=2,label='Light Denoise');
55
+ rand_steps_denoise_strong.plot(ax=ax,color='r',linewidth=2,linestyle='-',label='Strong Denoise')
56
+ ax.legend();
57
+ """
58
+ )
59
+
60
+ denoise_power_strong_select = st.sidebar.slider('Strong Denoise Strength',value=0.7,min_value=0.01,max_value=1.0,step=0.01)
61
+ denoise_power_light_select = st.sidebar.slider('Light Denoise Strength',value=0.2,min_value=0.01,max_value=1.0,step=0.01)
62
+ denoise_mode_select = st.sidebar.radio('Denoise Mode',('range','value'))
63
+
64
+ seq = Sequency()
65
+ #Create a sequence of steps that we can analyse
66
+ steps_changes = np.random.randint(-10,12,100)
67
+ rand_steps = Steps().add_direct(data_start=list(range(1,len(steps_changes))),data_weight = steps_changes)
68
+
69
+ denoise_step_changes_strong = seq.denoise(rand_steps.step_changes(),denoise_strength=denoise_power_strong_select,denoise_mode=denoise_mode_select)
70
+ denoise_step_changes = seq.denoise(rand_steps.step_changes(),denoise_strength=denoise_power_light_select,denoise_mode=denoise_mode_select)
71
+
72
+ rand_steps_denoise_strong = Steps().add_direct(data_start=rand_steps.step_keys(),data_weight = denoise_step_changes_strong)
73
+ rand_steps_denoise = Steps().add_direct(data_start=rand_steps.step_keys(),data_weight = denoise_step_changes)
74
+
75
+ ax = rand_steps.plot(label='Original Data')
76
+ rand_steps_denoise.plot(ax=ax,color='g',linewidth=2,label='Light Denoise')
77
+ rand_steps_denoise_strong.plot(ax=ax,color='r',linewidth=2,linestyle='-',label='Strong Denoise')
78
+ ax.legend()
79
+
80
+ st.pyplot(ax.get_figure(),clear_figure=True)
81
+
82
+
83
+ st.write(
84
+ """
85
+ As another quick example, we can apply the same technique to one of the HotStepper sample datasets, for this tutorial, we’ll only look at the first two months of data in order to better highlight what the sequency denoising can do to help better show the trend or typical step behaviour of the data.
86
+ """
87
+ )
88
+
89
+ st.code(
90
+ """
91
+ df_vq_samp = pd.read_csv(r'https://raw.githubusercontent.com/TangleSpace/hotstepper-data/master/data/vessel_queue.csv',parse_dates=['enter','leave'],dayfirst=True)
92
+
93
+ vq_samp = Steps.read_dataframe(df_vq_samp,start='enter',end='leave')
94
+ vq_clip = vq_samp.clip(ubound=pd.Timestamp(2020,3,1))
95
+
96
+ dn = seq.denoise(vq_clip.step_changes(),denoise_mode='range')
97
+ vq_clip_dn = Steps().add_direct(data_start=vq_clip.step_keys(convert_keys=True),data_weight=dn)
98
+
99
+ ax = vq_clip.plot(label='Original Data',figsize=(14,6))
100
+ vq_clip_dn.plot(ax=ax,linewidth=3,label='Sequency Denoise')
101
+ ax.legend()
102
+ """
103
+ )
104
+
105
+ vq_samp = Steps.read_dataframe(df_vq_samp,start='enter',end='leave')
106
+ vq_clip = vq_samp.clip(ubound=pd.Timestamp(2020,3,1))
107
+
108
+
109
+ dn_strong = seq.denoise(vq_clip.step_changes(),denoise_strength=denoise_power_strong_select,denoise_mode=denoise_mode_select)
110
+ dn_light = seq.denoise(vq_clip.step_changes(),denoise_strength=denoise_power_light_select,denoise_mode=denoise_mode_select)
111
+
112
+ vq_clip_dn_strong = Steps().add_direct(data_start=vq_clip.step_keys(convert_keys=True),data_weight=dn_strong)
113
+ vq_clip_dn_light = Steps().add_direct(data_start=vq_clip.step_keys(convert_keys=True),data_weight=dn_light)
114
+
115
+ ax = vq_clip.plot(label='Original Data',figsize=(14,6))
116
+ vq_clip_dn_strong.plot(ax=ax,linewidth=1.5,label='Strong Sequency Denoise')
117
+ vq_clip_dn_light.plot(ax=ax,linewidth=1.5,label='Light Sequency Denoise')
118
+ ax.legend()
119
+
120
+ st.pyplot(ax.get_figure(),clear_figure=True)
121
+
122
+ st.write(
123
+ """
124
+ As the last item, we can take a look at the sequency spectrum for the vessel queue data. This dataset has a large number of changes and therefore the sequency range goes quite high, however it does show a number of peaks that are significantly larger than the others, indicating a number of distinct and repeating step change patterns within the data over this period.
125
+ """
126
+ )
127
+
128
+ st.code(
129
+ """
130
+ fig, (ax,ax2,ax3) = plt.subplots(nrows=3,figsize=(12,8))
131
+ fig.tight_layout(h_pad=4)
132
+
133
+ # Sequency object to use for analysis
134
+ vq_clip_seq = Sequency()
135
+ n,sp,l = vq_clip_seq.sequency_spectrum(vq_clip.step_changes())
136
+
137
+
138
+ ax.set_title('Step Change Sequency Spectrum')
139
+ ax.set_xlabel('Sequency Number')
140
+ ax.set_ylabel('Amplitude')
141
+ ax.stem(n,sp)
142
+
143
+ # number of data points, needed to create the sampling frequency
144
+ no_points = vq_clip.step_changes().shape[0]
145
+
146
+ fr,fsp = vq_clip_seq.frequency_spectrum(vq_clip.step_changes(),2*np.pi*no_points)
147
+
148
+ ax2.set_title('Step Change Frequency Spectrum')
149
+ ax2.set_xlabel('Frequency')
150
+ ax2.set_ylabel('Amplitude')
151
+ ax2.stem(fr,fsp)
152
+
153
+ # FFT the steps values instead of the delta changes to see the difference in the spectrum.
154
+ frv,fspv = vq_clip_seq.frequency_spectrum(vq_clip.step_values(),2*np.pi*no_points)
155
+
156
+ ax3.set_title('Steps Value Frequency Spectrum')
157
+ ax3.set_xlabel('Frequency')
158
+ ax3.set_ylabel('Amplitude')
159
+ ax3.stem(frv[1:],fspv[1:]);
160
+ """
161
+ )
162
+
163
+
164
+ fig, (ax,ax2,ax3) = plt.subplots(nrows=3,figsize=(12,8))
165
+ fig.tight_layout(h_pad=4)
166
+
167
+ # Sequency object to use for analysis
168
+ vq_clip_seq = Sequency()
169
+ n,sp,l = vq_clip_seq.sequency_spectrum(vq_clip.step_changes())
170
+
171
+
172
+ ax.set_title('Step Change Sequency Spectrum')
173
+ ax.set_xlabel('Sequency Number')
174
+ ax.set_ylabel('Amplitude')
175
+ ax.stem(n,sp)
176
+
177
+ # number of data points, needed to create the sampling frequency
178
+ no_points = vq_clip.step_changes().shape[0]
179
+
180
+ fr,fsp = vq_clip_seq.frequency_spectrum(vq_clip.step_changes(),2*np.pi*no_points)
181
+
182
+ ax2.set_title('Step Change Frequency Spectrum')
183
+ ax2.set_xlabel('Frequency')
184
+ ax2.set_ylabel('Amplitude')
185
+ ax2.stem(fr,fsp)
186
+
187
+ # FFT the steps values instead of the delta changes to see the difference in the spectrum.
188
+ frv,fspv = vq_clip_seq.frequency_spectrum(vq_clip.step_values(),2*np.pi*no_points)
189
+
190
+ ax3.set_title('Steps Value Frequency Spectrum')
191
+ ax3.set_xlabel('Frequency')
192
+ ax3.set_ylabel('Amplitude')
193
+ ax3.stem(frv[1:],fspv[1:])
194
+
195
+ st.pyplot(fig,clear_figure=True)
196
+
197
+ else:
198
+ _,c1,c2 = st.columns([2,2,2])
199
+ c2.image("./resources/lock.png",width=100,)
200
+ c2.image("./resources/hydra.png",width=100,)
201
+ c1.error('Sorry {}, you don\'t have enough permission to use this application, check with your local diety for more permission and try again.'.format(username))
202
+ c1.info('Go back to the login screen (logout) and select a higher access level and try again.')
203
+
204
+
205
+
206
+ except Exception as e:
207
+ st.image("./resources/failure.png",width=100,)
208
+ st.error('An error has occurred, someone will be punished for your inconvenience, we humbly request you try again.')
209
+ st.error('Error details: {}'.format(e))
210
+
docs/images/hydra.png ADDED
js/exscripts.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+
2
+ function get_st_btns() {
3
+ var all_btn = $("button.stButton");
4
+ console.log(all_btn);
5
+ }
6
+
7
+ $(document).ready(function () {
8
+ console.log('Hello from Hydralit Experimental!');
9
+ });
requirements.txt ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ compress_pickle
2
+ hydralit >=1.0.9
3
+ hydralit_components >=1.0.4
4
+ streamlit >=0.89
5
+ numpy==1.20
6
+ hotstepper
7
+ altair
8
+ pandas
9
+ spacy
10
+ validators
11
+ bokeh
12
+ srsly
13
+ spacy-streamlit
14
+ astroquery
15
+ sunpy
16
+ astropy
17
+ pydeck
18
+ scipy
resources/belgium.png ADDED
resources/brain.png ADDED
resources/classroom.png ADDED
resources/dart.png ADDED
resources/data.png ADDED
resources/denoise.png ADDED
resources/exchange.png ADDED
resources/failure.png ADDED
resources/hydra.png ADDED
resources/jquery.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(g,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,v=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,y=n.hasOwnProperty,a=y.toString,l=a.call(Object),m={},b=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},w=g.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function C(e,t,n){var r,i,o=(n=n||w).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function T(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0 -ajax,-ajax/jsonp,-ajax/load,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-deprecated/ajax-event-alias,-effects,-effects/Tween,-effects/animatedSelector",E=function(e,t){return new E.fn.init(e,t)};function d(e){var t=!!e&&"length"in e&&e.length,n=T(e);return!b(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}E.fn=E.prototype={jquery:f,constructor:E,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=E.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return E.each(this,e)},map:function(n){return this.pushStack(E.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(E.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(E.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},E.extend=E.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||b(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(E.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||E.isPlainObject(n)?n:{},i=!1,a[t]=E.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},E.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=y.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){C(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(d(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},makeArray:function(e,t){var n=t||[];return null!=e&&(d(Object(e))?E.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(d(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return v(a)},guid:1,support:m}),"function"==typeof Symbol&&(E.fn[Symbol.iterator]=t[Symbol.iterator]),E.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var p=function(n){var e,p,x,o,i,h,f,g,w,u,l,C,T,a,E,v,s,c,y,A="sizzle"+1*new Date,d=n.document,N=0,r=0,m=ue(),b=ue(),S=ue(),k=ue(),D=function(e,t){return e===t&&(l=!0),0},L={}.hasOwnProperty,t=[],j=t.pop,q=t.push,O=t.push,P=t.slice,H=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},I="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",R="[\\x20\\t\\r\\n\\f]",B="(?:\\\\[\\da-fA-F]{1,6}"+R+"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",M="\\["+R+"*("+B+")(?:"+R+"*([*^$|!~]?=)"+R+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+B+"))|)"+R+"*\\]",W=":("+B+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",F=new RegExp(R+"+","g"),$=new RegExp("^"+R+"+|((?:^|[^\\\\])(?:\\\\.)*)"+R+"+$","g"),z=new RegExp("^"+R+"*,"+R+"*"),_=new RegExp("^"+R+"*([>+~]|"+R+")"+R+"*"),U=new RegExp(R+"|>"),V=new RegExp(W),X=new RegExp("^"+B+"$"),Q={ID:new RegExp("^#("+B+")"),CLASS:new RegExp("^\\.("+B+")"),TAG:new RegExp("^("+B+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+R+"*(even|odd|(([+-]|)(\\d*)n|)"+R+"*(?:([+-]|)"+R+"*(\\d+)|))"+R+"*\\)|)","i"),bool:new RegExp("^(?:"+I+")$","i"),needsContext:new RegExp("^"+R+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+R+"*((?:-\\d)?\\d*)"+R+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,G=/^(?:input|select|textarea|button)$/i,K=/^h\d$/i,J=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+R+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){C()},ae=xe(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{O.apply(t=P.call(d.childNodes),d.childNodes),t[d.childNodes.length].nodeType}catch(e){O={apply:t.length?function(e,t){q.apply(e,P.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,d=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==d&&9!==d&&11!==d)return n;if(!r&&(C(e),e=e||T,E)){if(11!==d&&(u=Z.exec(t)))if(i=u[1]){if(9===d){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return O.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&p.getElementsByClassName&&e.getElementsByClassName)return O.apply(n,e.getElementsByClassName(i)),n}if(p.qsa&&!k[t+" "]&&(!v||!v.test(t))&&(1!==d||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===d&&(U.test(t)||_.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&p.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=A)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+be(l[o]);c=l.join(",")}try{return O.apply(n,f.querySelectorAll(c)),n}catch(e){k(t,!0)}finally{s===A&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>x.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[A]=!0,e}function ce(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)x.attrHandle[n[r]]=t}function de(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function pe(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in p=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},C=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:d;return r!=T&&9===r.nodeType&&r.documentElement&&(a=(T=r).documentElement,E=!i(T),d!=T&&(n=T.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),p.scope=ce(function(e){return a.appendChild(e).appendChild(T.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),p.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),p.getElementsByTagName=ce(function(e){return e.appendChild(T.createComment("")),!e.getElementsByTagName("*").length}),p.getElementsByClassName=J.test(T.getElementsByClassName),p.getById=ce(function(e){return a.appendChild(e).id=A,!T.getElementsByName||!T.getElementsByName(A).length}),p.getById?(x.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},x.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(x.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},x.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),x.find.TAG=p.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):p.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},x.find.CLASS=p.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(p.qsa=J.test(T.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="<a id='"+A+"'></a><select id='"+A+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+R+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+R+"*(?:value|"+I+")"),e.querySelectorAll("[id~="+A+"-]").length||v.push("~="),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+R+"*name"+R+"*="+R+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+A+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=T.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+R+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(p.matchesSelector=J.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){p.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",W)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=J.test(a.compareDocumentPosition),y=t||J.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!p.sortDetached&&t.compareDocumentPosition(e)===n?e==T||e.ownerDocument==d&&y(d,e)?-1:t==T||t.ownerDocument==d&&y(d,t)?1:u?H(u,e)-H(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==T?-1:t==T?1:i?-1:o?1:u?H(u,e)-H(u,t):0;if(i===o)return de(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?de(a[r],s[r]):a[r]==d?-1:s[r]==d?1:0}),T},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(C(e),p.matchesSelector&&E&&!k[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||p.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){k(t,!0)}return 0<se(t,T,null,[e]).length},se.contains=function(e,t){return(e.ownerDocument||e)!=T&&C(e),y(e,t)},se.attr=function(e,t){(e.ownerDocument||e)!=T&&C(e);var n=x.attrHandle[t.toLowerCase()],r=n&&L.call(x.attrHandle,t.toLowerCase())?n(e,t,!E):void 0;return void 0!==r?r:p.attributes||!E?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},se.escape=function(e){return(e+"").replace(re,ie)},se.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},se.uniqueSort=function(e){var t,n=[],r=0,i=0;if(l=!p.detectDuplicates,u=!p.sortStable&&e.slice(0),e.sort(D),l){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)e.splice(n[r],1)}return u=null,e},o=se.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else while(t=e[r++])n+=o(t);return n},(x=se.selectors={cacheLength:50,createPseudo:le,match:Q,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&V.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+R+")"+e+"("+R+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1<t.indexOf(i):"$="===r?i&&t.slice(-i.length)===i:"~="===r?-1<(" "+t.replace(F," ")+" ").indexOf(i):"|="===r&&(t===i||t.slice(0,i.length+1)===i+"-"))}},CHILD:function(h,e,t,g,v){var y="nth"!==h.slice(0,3),m="last"!==h.slice(-4),b="of-type"===e;return 1===g&&0===v?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u,l=y!==m?"nextSibling":"previousSibling",c=e.parentNode,f=b&&e.nodeName.toLowerCase(),d=!n&&!b,p=!1;if(c){if(y){while(l){a=e;while(a=a[l])if(b?a.nodeName.toLowerCase()===f:1===a.nodeType)return!1;u=l="only"===h&&!u&&"nextSibling"}return!0}if(u=[m?c.firstChild:c.lastChild],m&&d){p=(s=(r=(i=(o=(a=c)[A]||(a[A]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===N&&r[1])&&r[2],a=s&&c.childNodes[s];while(a=++s&&a&&a[l]||(p=s=0)||u.pop())if(1===a.nodeType&&++p&&a===e){i[h]=[N,s,p];break}}else if(d&&(p=s=(r=(i=(o=(a=e)[A]||(a[A]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===N&&r[1]),!1===p)while(a=++s&&a&&a[l]||(p=s=0)||u.pop())if((b?a.nodeName.toLowerCase()===f:1===a.nodeType)&&++p&&(d&&((i=(o=a[A]||(a[A]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]=[N,p]),a===e))break;return(p-=v)===g||p%g==0&&0<=p/g}}},PSEUDO:function(e,o){var t,a=x.pseudos[e]||x.setFilters[e.toLowerCase()]||se.error("unsupported pseudo: "+e);return a[A]?a(o):1<a.length?(t=[e,e,"",o],x.setFilters.hasOwnProperty(e.toLowerCase())?le(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=H(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:le(function(e){var r=[],i=[],s=f(e.replace($,"$1"));return s[A]?le(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:le(function(t){return function(e){return 0<se(t,e).length}}),contains:le(function(t){return t=t.replace(te,ne),function(e){return-1<(e.textContent||o(e)).indexOf(t)}}),lang:le(function(n){return X.test(n||"")||se.error("unsupported lang: "+n),n=n.replace(te,ne).toLowerCase(),function(e){var t;do{if(t=E?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(t=t.toLowerCase())===n||0===t.indexOf(n+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=n.location&&n.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===a},focus:function(e){return e===T.activeElement&&(!T.hasFocus||T.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ge(!1),disabled:ge(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!x.pseudos.empty(e)},header:function(e){return K.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:ve(function(){return[0]}),last:ve(function(e,t){return[t-1]}),eq:ve(function(e,t,n){return[n<0?n+t:n]}),even:ve(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:ve(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:ve(function(e,t,n){for(var r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:ve(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=x.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})x.pseudos[e]=pe(e);for(e in{submit:!0,reset:!0})x.pseudos[e]=he(e);function me(){}function be(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function xe(s,e,t){var u=e.dir,l=e.next,c=l||u,f=t&&"parentNode"===c,d=r++;return e.first?function(e,t,n){while(e=e[u])if(1===e.nodeType||f)return s(e,t,n);return!1}:function(e,t,n){var r,i,o,a=[N,d];if(n){while(e=e[u])if((1===e.nodeType||f)&&s(e,t,n))return!0}else while(e=e[u])if(1===e.nodeType||f)if(i=(o=e[A]||(e[A]={}))[e.uniqueID]||(o[e.uniqueID]={}),l&&l===e.nodeName.toLowerCase())e=e[u]||e;else{if((r=i[c])&&r[0]===N&&r[1]===d)return a[2]=r[2];if((i[c]=a)[2]=s(e,t,n))return!0}return!1}}function we(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function Ce(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Te(p,h,g,v,y,e){return v&&!v[A]&&(v=Te(v)),y&&!y[A]&&(y=Te(y,e)),le(function(e,t,n,r){var i,o,a,s=[],u=[],l=t.length,c=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)se(e,t[r],n);return n}(h||"*",n.nodeType?[n]:n,[]),f=!p||!e&&h?c:Ce(c,s,p,n,r),d=g?y||(e?p:l||v)?[]:t:f;if(g&&g(f,d,n,r),v){i=Ce(d,u),v(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(d[u[o]]=!(f[u[o]]=a))}if(e){if(y||p){if(y){i=[],o=d.length;while(o--)(a=d[o])&&i.push(f[o]=a);y(null,d=[],i,r)}o=d.length;while(o--)(a=d[o])&&-1<(i=y?H(e,a):s[o])&&(e[i]=!(t[i]=a))}}else d=Ce(d===t?d.splice(l,d.length):d),y?y(null,t,d,r):O.apply(t,d)})}function Ee(e){for(var i,t,n,r=e.length,o=x.relative[e[0].type],a=o||x.relative[" "],s=o?1:0,u=xe(function(e){return e===i},a,!0),l=xe(function(e){return-1<H(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!==w)||((i=t).nodeType?u(e,t,n):l(e,t,n));return i=null,r}];s<r;s++)if(t=x.relative[e[s].type])c=[xe(we(c),t)];else{if((t=x.filter[e[s].type].apply(null,e[s].matches))[A]){for(n=++s;n<r;n++)if(x.relative[e[n].type])break;return Te(1<s&&we(c),1<s&&be(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace($,"$1"),t,s<n&&Ee(e.slice(s,n)),n<r&&Ee(e=e.slice(n)),n<r&&be(e))}c.push(t)}return we(c)}return me.prototype=x.filters=x.pseudos,x.setFilters=new me,h=se.tokenize=function(e,t){var n,r,i,o,a,s,u,l=b[e+" "];if(l)return t?0:l.slice(0);a=e,s=[],u=x.preFilter;while(a){for(o in n&&!(r=z.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=_.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace($," ")}),a=a.slice(n.length)),x.filter)!(r=Q[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?se.error(e):b(e,s).slice(0)},f=se.compile=function(e,t){var n,v,y,m,b,r,i=[],o=[],a=S[e+" "];if(!a){t||(t=h(e)),n=t.length;while(n--)(a=Ee(t[n]))[A]?i.push(a):o.push(a);(a=S(e,(v=o,m=0<(y=i).length,b=0<v.length,r=function(e,t,n,r,i){var o,a,s,u=0,l="0",c=e&&[],f=[],d=w,p=e||b&&x.find.TAG("*",i),h=N+=null==d?1:Math.random()||.1,g=p.length;for(i&&(w=t==T||t||i);l!==g&&null!=(o=p[l]);l++){if(b&&o){a=0,t||o.ownerDocument==T||(C(o),n=!E);while(s=v[a++])if(s(o,t||T,n)){r.push(o);break}i&&(N=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){a=0;while(s=y[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=j.call(r));f=Ce(f)}O.apply(r,f),i&&!e&&0<f.length&&1<u+y.length&&se.uniqueSort(r)}return i&&(N=h,w=d),c},m?le(r):r))).selector=e}return a},g=se.select=function(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,c=!r&&h(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&"ID"===(a=o[0]).type&&9===t.nodeType&&E&&x.relative[o[1].type]){if(!(t=(x.find.ID(a.matches[0].replace(te,ne),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=Q.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],x.relative[s=a.type])break;if((u=x.find[s])&&(r=u(a.matches[0].replace(te,ne),ee.test(o[0].type)&&ye(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&be(o)))return O.apply(n,r),n;break}}}return(l||f(e,c))(r,t,!E,n,!t||ee.test(e)&&ye(t.parentNode)||t),n},p.sortStable=A.split("").sort(D).join("")===A,p.detectDuplicates=!!l,C(),p.sortDetached=ce(function(e){return 1&e.compareDocumentPosition(T.createElement("fieldset"))}),ce(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||fe("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),p.attributes&&ce(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||fe("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ce(function(e){return null==e.getAttribute("disabled")})||fe(I,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),se}(g);E.find=p,E.expr=p.selectors,E.expr[":"]=E.expr.pseudos,E.uniqueSort=E.unique=p.uniqueSort,E.text=p.getText,E.isXMLDoc=p.isXML,E.contains=p.contains,E.escapeSelector=p.escape;var h=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&E(e).is(n))break;r.push(e)}return r},A=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},N=E.expr.match.needsContext;function S(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var k=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return b(n)?E.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?E.grep(e,function(e){return e===n!==r}):"string"!=typeof n?E.grep(e,function(e){return-1<i.call(n,e)!==r}):E.filter(n,e,r)}E.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?E.find.matchesSelector(r,e)?[r]:[]:E.find.matches(e,E.grep(t,function(e){return 1===e.nodeType}))},E.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(E(e).filter(function(){for(t=0;t<r;t++)if(E.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)E.find(e,i[t],n);return 1<r?E.uniqueSort(n):n},filter:function(e){return this.pushStack(D(this,e||[],!1))},not:function(e){return this.pushStack(D(this,e||[],!0))},is:function(e){return!!D(this,"string"==typeof e&&N.test(e)?E(e):e||[],!1).length}});var L,j=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(E.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||L,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:j.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof E?t[0]:t,E.merge(this,E.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:w,!0)),k.test(r[1])&&E.isPlainObject(t))for(r in t)b(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=w.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):b(e)?void 0!==n.ready?n.ready(e):e(E):E.makeArray(e,this)}).prototype=E.fn,L=E(w);var q=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}E.fn.extend({has:function(e){var t=E(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(E.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&E(e);if(!N.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&E.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?E.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?i.call(E(e),this[0]):i.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(E.uniqueSort(E.merge(this.get(),E(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),E.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return h(e,"parentNode")},parentsUntil:function(e,t,n){return h(e,"parentNode",n)},next:function(e){return P(e,"nextSibling")},prev:function(e){return P(e,"previousSibling")},nextAll:function(e){return h(e,"nextSibling")},prevAll:function(e){return h(e,"previousSibling")},nextUntil:function(e,t,n){return h(e,"nextSibling",n)},prevUntil:function(e,t,n){return h(e,"previousSibling",n)},siblings:function(e){return A((e.parentNode||{}).firstChild,e)},children:function(e){return A(e.firstChild)},contents:function(e){return null!=e.contentDocument&&r(e.contentDocument)?e.contentDocument:(S(e,"template")&&(e=e.content||e),E.merge([],e.childNodes))}},function(r,i){E.fn[r]=function(e,t){var n=E.map(this,i,e);return"Until"!==r.slice(-5)&&(t=e),t&&"string"==typeof t&&(n=E.filter(t,n)),1<this.length&&(O[r]||E.uniqueSort(n),q.test(r)&&n.reverse()),this.pushStack(n)}});var H=/[^\x20\t\r\n\f]+/g;function I(e){return e}function R(e){throw e}function B(e,t,n,r){var i;try{e&&b(i=e.promise)?i.call(e).done(t).fail(n):e&&b(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}E.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},E.each(e.match(H)||[],function(e,t){n[t]=!0}),n):E.extend({},r);var i,t,o,a,s=[],u=[],l=-1,c=function(){for(a=a||r.once,o=i=!0;u.length;l=-1){t=u.shift();while(++l<s.length)!1===s[l].apply(t[0],t[1])&&r.stopOnFalse&&(l=s.length,t=!1)}r.memory||(t=!1),i=!1,a&&(s=t?[]:"")},f={add:function(){return s&&(t&&!i&&(l=s.length-1,u.push(t)),function n(e){E.each(e,function(e,t){b(t)?r.unique&&f.has(t)||s.push(t):t&&t.length&&"string"!==T(t)&&n(t)})}(arguments),t&&!i&&c()),this},remove:function(){return E.each(arguments,function(e,t){var n;while(-1<(n=E.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<E.inArray(e,s):0<s.length},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=t="",this},disabled:function(){return!s},lock:function(){return a=u=[],t||i||(s=t=""),this},locked:function(){return!!a},fireWith:function(e,t){return a||(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),i||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},E.extend({Deferred:function(e){var o=[["notify","progress",E.Callbacks("memory"),E.Callbacks("memory"),2],["resolve","done",E.Callbacks("once memory"),E.Callbacks("once memory"),0,"resolved"],["reject","fail",E.Callbacks("once memory"),E.Callbacks("once memory"),1,"rejected"]],i="pending",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},"catch":function(e){return a.then(null,e)},pipe:function(){var i=arguments;return E.Deferred(function(r){E.each(o,function(e,t){var n=b(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&b(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+"With"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError("Thenable self-resolution");t=e&&("object"==typeof e||"function"==typeof e)&&e.then,b(t)?s?t.call(e,l(u,o,I,s),l(u,o,R,s)):(u++,t.call(e,l(u,o,I,s),l(u,o,R,s),l(u,o,I,o.notifyWith))):(a!==I&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){E.Deferred.exceptionHook&&E.Deferred.exceptionHook(e,t.stackTrace),u<=i+1&&(a!==R&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(E.Deferred.getStackHook&&(t.stackTrace=E.Deferred.getStackHook()),g.setTimeout(t))}}return E.Deferred(function(e){o[0][3].add(l(0,e,b(r)?r:I,e.notifyWith)),o[1][3].add(l(0,e,b(t)?t:I)),o[2][3].add(l(0,e,b(n)?n:R))}).promise()},promise:function(e){return null!=e?E.extend(e,a):a}},s={};return E.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+"With"](this===s?void 0:this,arguments),this},s[t[0]+"With"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){var n=arguments.length,t=n,r=Array(t),i=s.call(arguments),o=E.Deferred(),a=function(t){return function(e){r[t]=this,i[t]=1<arguments.length?s.call(arguments):e,--n||o.resolveWith(r,i)}};if(n<=1&&(B(e,o.done(a(t)).resolve,o.reject,!n),"pending"===o.state()||b(i[t]&&i[t].then)))return o.then();while(t--)B(i[t],a(t),o.reject);return o.promise()}});var M=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;E.Deferred.exceptionHook=function(e,t){g.console&&g.console.warn&&e&&M.test(e.name)&&g.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},E.readyException=function(e){g.setTimeout(function(){throw e})};var W=E.Deferred();function F(){w.removeEventListener("DOMContentLoaded",F),g.removeEventListener("load",F),E.ready()}E.fn.ready=function(e){return W.then(e)["catch"](function(e){E.readyException(e)}),this},E.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--E.readyWait:E.isReady)||(E.isReady=!0)!==e&&0<--E.readyWait||W.resolveWith(w,[E])}}),E.ready.then=W.then,"complete"===w.readyState||"loading"!==w.readyState&&!w.documentElement.doScroll?g.setTimeout(E.ready):(w.addEventListener("DOMContentLoaded",F),g.addEventListener("load",F));var $=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===T(n))for(s in i=!0,n)$(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,b(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(E(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},z=/^-ms-/,_=/-([a-z])/g;function U(e,t){return t.toUpperCase()}function V(e){return e.replace(z,"ms-").replace(_,U)}var X=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function Q(){this.expando=E.expando+Q.uid++}Q.uid=1,Q.prototype={cache:function(e){var t=e[this.expando];return t||(t={},X(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[V(t)]=n;else for(r in t)i[V(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][V(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(V):(t=V(t))in r?[t]:t.match(H)||[]).length;while(n--)delete r[t[n]]}(void 0===t||E.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!E.isEmptyObject(t)}};var Y=new Q,G=new Q,K=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,J=/[A-Z]/g;function Z(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(J,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===(i=n)||"false"!==i&&("null"===i?null:i===+i+""?+i:K.test(i)?JSON.parse(i):i)}catch(e){}G.set(e,t,n)}else n=void 0;return n}E.extend({hasData:function(e){return G.hasData(e)||Y.hasData(e)},data:function(e,t,n){return G.access(e,t,n)},removeData:function(e,t){G.remove(e,t)},_data:function(e,t,n){return Y.access(e,t,n)},_removeData:function(e,t){Y.remove(e,t)}}),E.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0===n){if(this.length&&(i=G.get(o),1===o.nodeType&&!Y.get(o,"hasDataAttrs"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf("data-")&&(r=V(r.slice(5)),Z(o,r,i[r]));Y.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof n?this.each(function(){G.set(this,n)}):$(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=G.get(o,n))?t:void 0!==(t=Z(o,n))?t:void 0;this.each(function(){G.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){G.remove(this,e)})}}),E.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Y.get(e,t),n&&(!r||Array.isArray(n)?r=Y.access(e,t,E.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=E.queue(e,t),r=n.length,i=n.shift(),o=E._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){E.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Y.get(e,n)||Y.access(e,n,{empty:E.Callbacks("once memory").add(function(){Y.remove(e,[t+"queue",n])})})}}),E.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?E.queue(this[0],t):void 0===n?this:this.each(function(){var e=E.queue(this,t,n);E._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&E.dequeue(this,t)})},dequeue:function(e){return this.each(function(){E.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=E.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=Y.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var ee=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,te=new RegExp("^(?:([+-])=|)("+ee+")([a-z%]*)$","i"),ne=["Top","Right","Bottom","Left"],re=w.documentElement,ie=function(e){return E.contains(e.ownerDocument,e)},oe={composed:!0};re.getRootNode&&(ie=function(e){return E.contains(e.ownerDocument,e)||e.getRootNode(oe)===e.ownerDocument});var ae=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&ie(e)&&"none"===E.css(e,"display")};var se={};function ue(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?("none"===n&&(l[c]=Y.get(r,"display")||null,l[c]||(r.style.display="")),""===r.style.display&&ae(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=se[s])||(o=a.body.appendChild(a.createElement(s)),u=E.css(o,"display"),o.parentNode.removeChild(o),"none"===u&&(u="block"),se[s]=u)))):"none"!==n&&(l[c]="none",Y.set(r,"display",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}E.fn.extend({show:function(){return ue(this,!0)},hide:function(){return ue(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){ae(this)?E(this).show():E(this).hide()})}});var le,ce,fe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i,pe=/^$|^module$|\/(?:java|ecma)script/i;le=w.createDocumentFragment().appendChild(w.createElement("div")),(ce=w.createElement("input")).setAttribute("type","radio"),ce.setAttribute("checked","checked"),ce.setAttribute("name","t"),le.appendChild(ce),m.checkClone=le.cloneNode(!0).cloneNode(!0).lastChild.checked,le.innerHTML="<textarea>x</textarea>",m.noCloneChecked=!!le.cloneNode(!0).lastChild.defaultValue,le.innerHTML="<option></option>",m.option=!!le.lastChild;var he={thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};function ge(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&S(e,t)?E.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n<r;n++)Y.set(e[n],"globalEval",!t||Y.get(t[n],"globalEval"))}he.tbody=he.tfoot=he.colgroup=he.caption=he.thead,he.th=he.td,m.option||(he.optgroup=he.option=[1,"<select multiple='multiple'>","</select>"]);var ye=/<|&#?\w+;/;function me(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),d=[],p=0,h=e.length;p<h;p++)if((o=e[p])||0===o)if("object"===T(o))E.merge(d,o.nodeType?[o]:o);else if(ye.test(o)){a=a||f.appendChild(t.createElement("div")),s=(de.exec(o)||["",""])[1].toLowerCase(),u=he[s]||he._default,a.innerHTML=u[1]+E.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;E.merge(d,a.childNodes),(a=f.firstChild).textContent=""}else d.push(t.createTextNode(o));f.textContent="",p=0;while(o=d[p++])if(r&&-1<E.inArray(o,r))i&&i.push(o);else if(l=ie(o),a=ge(f.appendChild(o),"script"),l&&ve(a),n){c=0;while(o=a[c++])pe.test(o.type||"")&&n.push(o)}return f}var be=/^([^.]*)(?:\.(.+)|)/;function xe(){return!0}function we(){return!1}function Ce(e,t){return e===function(){try{return w.activeElement}catch(e){}}()==("focus"===t)}function Te(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Te(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=we;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return E().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=E.guid++)),e.each(function(){E.event.add(this,t,i,r,n)})}function Ee(e,i,o){o?(Y.set(e,i,!1),E.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Y.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(E.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Y.set(this,i,r),t=o(this,i),this[i](),r!==(n=Y.get(this,i))||t?Y.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n&&n.value}else r.length&&(Y.set(this,i,{value:E.event.trigger(E.extend(r[0],E.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Y.get(e,i)&&E.event.add(e,i,xe)}E.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,d,p,h,g,v=Y.get(t);if(X(t)){n.handler&&(n=(o=n).handler,i=o.selector),i&&E.find.matchesSelector(re,i),n.guid||(n.guid=E.guid++),(u=v.events)||(u=v.events=Object.create(null)),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof E&&E.event.triggered!==e.type?E.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(H)||[""]).length;while(l--)p=g=(s=be.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),p&&(f=E.event.special[p]||{},p=(i?f.delegateType:f.bindType)||p,f=E.event.special[p]||{},c=E.extend({type:p,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&E.expr.match.needsContext.test(i),namespace:h.join(".")},o),(d=u[p])||((d=u[p]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(p,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?d.splice(d.delegateCount++,0,c):d.push(c),E.event.global[p]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,d,p,h,g,v=Y.hasData(e)&&Y.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(H)||[""]).length;while(l--)if(p=g=(s=be.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),p){f=E.event.special[p]||{},d=u[p=(r?f.delegateType:f.bindType)||p]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=d.length;while(o--)c=d[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(d.splice(o,1),c.selector&&d.delegateCount--,f.remove&&f.remove.call(e,c));a&&!d.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||E.removeEvent(e,p,v.handle),delete u[p])}else for(p in u)E.event.remove(e,p+t[l],n,r,!0);E.isEmptyObject(u)&&Y.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=new Array(arguments.length),u=E.event.fix(e),l=(Y.get(this,"events")||Object.create(null))[u.type]||[],c=E.event.special[u.type]||{};for(s[0]=u,t=1;t<arguments.length;t++)s[t]=arguments[t];if(u.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,u)){a=E.event.handlers.call(this,u,l),t=0;while((i=a[t++])&&!u.isPropagationStopped()){u.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!u.isImmediatePropagationStopped())u.rnamespace&&!1!==o.namespace&&!u.rnamespace.test(o.namespace)||(u.handleObj=o,u.data=o.data,void 0!==(r=((E.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s))&&!1===(u.result=r)&&(u.preventDefault(),u.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,u),u.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?-1<E(i,this).index(l):E.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(E.Event.prototype,t,{enumerable:!0,configurable:!0,get:b(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[E.expando]?e:new E.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return fe.test(t.type)&&t.click&&S(t,"input")&&Ee(t,"click",xe),!1},trigger:function(e){var t=this||e;return fe.test(t.type)&&t.click&&S(t,"input")&&Ee(t,"click"),!0},_default:function(e){var t=e.target;return fe.test(t.type)&&t.click&&S(t,"input")&&Y.get(t,"click")||S(t,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},E.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},E.Event=function(e,t){if(!(this instanceof E.Event))return new E.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?xe:we,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&E.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[E.expando]=!0},E.Event.prototype={constructor:E.Event,isDefaultPrevented:we,isPropagationStopped:we,isImmediatePropagationStopped:we,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=xe,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=xe,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=xe,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},E.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:!0},E.event.addProp),E.each({focus:"focusin",blur:"focusout"},function(e,t){E.event.special[e]={setup:function(){return Ee(this,e,Ce),!1},trigger:function(){return Ee(this,e),!0},_default:function(){return!0},delegateType:t}}),E.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){E.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||E.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),E.fn.extend({on:function(e,t,n,r){return Te(this,e,t,n,r)},one:function(e,t,n,r){return Te(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,E(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=we),this.each(function(){E.event.remove(this,e,n,t)})}});var Ae=/<script|<style|<link/i,Ne=/checked\s*(?:[^=]|=\s*.checked.)/i,Se=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function ke(e,t){return S(e,"table")&&S(11!==t.nodeType?t:t.firstChild,"tr")&&E(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Le(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function je(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n<r;n++)E.event.add(t,i,s[i][n]);G.hasData(e)&&(o=G.access(e),a=E.extend({},o),G.set(t,a))}}function qe(n,r,i,o){r=v(r);var e,t,a,s,u,l,c=0,f=n.length,d=f-1,p=r[0],h=b(p);if(h||1<f&&"string"==typeof p&&!m.checkClone&&Ne.test(p))return n.each(function(e){var t=n.eq(e);h&&(r[0]=p.call(this,e,t.html())),qe(t,r,i,o)});if(f&&(t=(e=me(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=E.map(ge(e,"script"),De)).length;c<f;c++)u=e,c!==d&&(u=E.clone(u,!0,!0),s&&E.merge(a,ge(u,"script"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,E.map(a,Le),c=0;c<s;c++)u=a[c],pe.test(u.type||"")&&!Y.access(u,"globalEval")&&E.contains(l,u)&&(u.src&&"module"!==(u.type||"").toLowerCase()?E._evalUrl&&!u.noModule&&E._evalUrl(u.src,{nonce:u.nonce||u.getAttribute("nonce")},l):C(u.textContent.replace(Se,""),u,l))}return n}function Oe(e,t,n){for(var r,i=t?E.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||E.cleanData(ge(r)),r.parentNode&&(n&&ie(r)&&ve(ge(r,"script")),r.parentNode.removeChild(r));return e}E.extend({htmlPrefilter:function(e){return e},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=ie(e);if(!(m.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||E.isXMLDoc(e)))for(a=ge(c),r=0,i=(o=ge(e)).length;r<i;r++)s=o[r],u=a[r],void 0,"input"===(l=u.nodeName.toLowerCase())&&fe.test(s.type)?u.checked=s.checked:"input"!==l&&"textarea"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||ge(e),a=a||ge(c),r=0,i=o.length;r<i;r++)je(o[r],a[r]);else je(e,c);return 0<(a=ge(c,"script")).length&&ve(a,!f&&ge(e,"script")),c},cleanData:function(e){for(var t,n,r,i=E.event.special,o=0;void 0!==(n=e[o]);o++)if(X(n)){if(t=n[Y.expando]){if(t.events)for(r in t.events)i[r]?E.event.remove(n,r):E.removeEvent(n,r,t.handle);n[Y.expando]=void 0}n[G.expando]&&(n[G.expando]=void 0)}}}),E.fn.extend({detach:function(e){return Oe(this,e,!0)},remove:function(e){return Oe(this,e)},text:function(e){return $(this,function(e){return void 0===e?E.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return qe(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||ke(this,e).appendChild(e)})},prepend:function(){return qe(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=ke(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return qe(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return qe(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(E.cleanData(ge(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return E.clone(this,e,t)})},html:function(e){return $(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ae.test(e)&&!he[(de.exec(e)||["",""])[1].toLowerCase()]){e=E.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(E.cleanData(ge(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return qe(this,arguments,function(e){var t=this.parentNode;E.inArray(this,n)<0&&(E.cleanData(ge(this)),t&&t.replaceChild(e,this))},n)}}),E.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){E.fn[e]=function(e){for(var t,n=[],r=E(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),E(r[o])[a](t),u.apply(n,t.get());return this.pushStack(n)}});var Pe=new RegExp("^("+ee+")(?!px)[a-z%]+$","i"),He=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=g),t.getComputedStyle(e)},Ie=function(e,t,n){var r,i,o={};for(i in t)o[i]=e.style[i],e.style[i]=t[i];for(i in r=n.call(e),t)e.style[i]=o[i];return r},Re=new RegExp(ne.join("|"),"i");function Be(e,t,n){var r,i,o,a,s=e.style;return(n=n||He(e))&&(""!==(a=n.getPropertyValue(t)||n[t])||ie(e)||(a=E.style(e,t)),!m.pixelBoxStyles()&&Pe.test(a)&&Re.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function Me(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(l){u.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",l.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",re.appendChild(u).appendChild(l);var e=g.getComputedStyle(l);n="1%"!==e.top,s=12===t(e.marginLeft),l.style.right="60%",o=36===t(e.right),r=36===t(e.width),l.style.position="absolute",i=12===t(l.offsetWidth/3),re.removeChild(u),l=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s,u=w.createElement("div"),l=w.createElement("div");l.style&&(l.style.backgroundClip="content-box",l.cloneNode(!0).style.backgroundClip="",m.clearCloneStyle="content-box"===l.style.backgroundClip,E.extend(m,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),s},scrollboxSize:function(){return e(),i},reliableTrDimensions:function(){var e,t,n,r;return null==a&&(e=w.createElement("table"),t=w.createElement("tr"),n=w.createElement("div"),e.style.cssText="position:absolute;left:-11111px;border-collapse:separate",t.style.cssText="border:1px solid",t.style.height="1px",n.style.height="9px",n.style.display="block",re.appendChild(e).appendChild(t).appendChild(n),r=g.getComputedStyle(t),a=parseInt(r.height,10)+parseInt(r.borderTopWidth,10)+parseInt(r.borderBottomWidth,10)===t.offsetHeight,re.removeChild(e)),a}}))}();var We=["Webkit","Moz","ms"],Fe=w.createElement("div").style,$e={};function ze(e){var t=E.cssProps[e]||$e[e];return t||(e in Fe?e:$e[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=We.length;while(n--)if((e=We[n]+t)in Fe)return e}(e)||e)}var _e,Ue,Ve=/^(none|table(?!-c[ea]).+)/,Xe=/^--/,Qe={position:"absolute",visibility:"hidden",display:"block"},Ye={letterSpacing:"0",fontWeight:"400"};function Ge(e,t,n){var r=te.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function Ke(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=E.css(e,n+ne[a],!0,i)),r?("content"===n&&(u-=E.css(e,"padding"+ne[a],!0,i)),"margin"!==n&&(u-=E.css(e,"border"+ne[a]+"Width",!0,i))):(u+=E.css(e,"padding"+ne[a],!0,i),"padding"!==n?u+=E.css(e,"border"+ne[a]+"Width",!0,i):s+=E.css(e,"border"+ne[a]+"Width",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u}function Je(e,t,n){var r=He(e),i=(!m.boxSizingReliable()||n)&&"border-box"===E.css(e,"boxSizing",!1,r),o=i,a=Be(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if(Pe.test(a)){if(!n)return a;a="auto"}return(!m.boxSizingReliable()&&i||!m.reliableTrDimensions()&&S(e,"tr")||"auto"===a||!parseFloat(a)&&"inline"===E.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===E.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+Ke(e,t,n||(i?"border":"content"),o,r,a)+"px"}E.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Be(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=V(t),u=Xe.test(t),l=e.style;if(u||(t=ze(s)),a=E.cssHooks[t]||E.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=te.exec(n))&&i[1]&&(n=function(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return E.css(e,t,"")},u=s(),l=n&&n[3]||(E.cssNumber[t]?"":"px"),c=e.nodeType&&(E.cssNumber[t]||"px"!==l&&+u)&&te.exec(E.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)E.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,E.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}(e,t,i),o="number"),null!=n&&n==n&&("number"!==o||u||(n+=i&&i[3]||(E.cssNumber[s]?"":"px")),m.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=V(t);return Xe.test(t)||(t=ze(s)),(a=E.cssHooks[t]||E.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Be(e,t,r)),"normal"===i&&t in Ye&&(i=Ye[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),E.each(["height","width"],function(e,u){E.cssHooks[u]={get:function(e,t,n){if(t)return!Ve.test(E.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?Je(e,u,n):Ie(e,Qe,function(){return Je(e,u,n)})},set:function(e,t,n){var r,i=He(e),o=!m.scrollboxSize()&&"absolute"===i.position,a=(o||n)&&"border-box"===E.css(e,"boxSizing",!1,i),s=n?Ke(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e["offset"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-Ke(e,u,"border",!1,i)-.5)),s&&(r=te.exec(t))&&"px"!==(r[3]||"px")&&(e.style[u]=t,t=E.css(e,u)),Ge(0,t,s)}}}),E.cssHooks.marginLeft=Me(m.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Be(e,"marginLeft"))||e.getBoundingClientRect().left-Ie(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),E.each({margin:"",padding:"",border:"Width"},function(i,o){E.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+ne[t]+o]=r[t]||r[t-2]||r[0];return n}},"margin"!==i&&(E.cssHooks[i+o].set=Ge)}),E.fn.extend({css:function(e,t){return $(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=He(e),i=t.length;a<i;a++)o[t[a]]=E.css(e,t[a],!1,r);return o}return void 0!==n?E.style(e,t,n):E.css(e,t)},e,t,1<arguments.length)}}),E.fn.delay=function(r,e){return r=E.fx&&E.fx.speeds[r]||r,e=e||"fx",this.queue(e,function(e,t){var n=g.setTimeout(e,r);t.stop=function(){g.clearTimeout(n)}})},_e=w.createElement("input"),Ue=w.createElement("select").appendChild(w.createElement("option")),_e.type="checkbox",m.checkOn=""!==_e.value,m.optSelected=Ue.selected,(_e=w.createElement("input")).value="t",_e.type="radio",m.radioValue="t"===_e.value;var Ze,et=E.expr.attrHandle;E.fn.extend({attr:function(e,t){return $(this,E.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){E.removeAttr(this,e)})}}),E.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?E.prop(e,t,n):(1===o&&E.isXMLDoc(e)||(i=E.attrHooks[t.toLowerCase()]||(E.expr.match.bool.test(t)?Ze:void 0)),void 0!==n?null===n?void E.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=E.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!m.radioValue&&"radio"===t&&S(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(H);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),Ze={set:function(e,t,n){return!1===t?E.removeAttr(e,n):e.setAttribute(n,n),n}},E.each(E.expr.match.bool.source.match(/\w+/g),function(e,t){var a=et[t]||E.find.attr;et[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=et[o],et[o]=r,r=null!=a(e,t,n)?o:null,et[o]=i),r}});var tt=/^(?:input|select|textarea|button)$/i,nt=/^(?:a|area)$/i;function rt(e){return(e.match(H)||[]).join(" ")}function it(e){return e.getAttribute&&e.getAttribute("class")||""}function ot(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(H)||[]}E.fn.extend({prop:function(e,t){return $(this,E.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[E.propFix[e]||e]})}}),E.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&E.isXMLDoc(e)||(t=E.propFix[t]||t,i=E.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=E.find.attr(e,"tabindex");return t?parseInt(t,10):tt.test(e.nodeName)||nt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),m.optSelected||(E.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),E.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){E.propFix[this.toLowerCase()]=this}),E.fn.extend({addClass:function(t){var e,n,r,i,o,a,s,u=0;if(b(t))return this.each(function(e){E(this).addClass(t.call(this,e,it(this)))});if((e=ot(t)).length)while(n=this[u++])if(i=it(n),r=1===n.nodeType&&" "+rt(i)+" "){a=0;while(o=e[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=rt(r))&&n.setAttribute("class",s)}return this},removeClass:function(t){var e,n,r,i,o,a,s,u=0;if(b(t))return this.each(function(e){E(this).removeClass(t.call(this,e,it(this)))});if(!arguments.length)return this.attr("class","");if((e=ot(t)).length)while(n=this[u++])if(i=it(n),r=1===n.nodeType&&" "+rt(i)+" "){a=0;while(o=e[a++])while(-1<r.indexOf(" "+o+" "))r=r.replace(" "+o+" "," ");i!==(s=rt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(i,t){var o=typeof i,a="string"===o||Array.isArray(i);return"boolean"==typeof t&&a?t?this.addClass(i):this.removeClass(i):b(i)?this.each(function(e){E(this).toggleClass(i.call(this,e,it(this),t),t)}):this.each(function(){var e,t,n,r;if(a){t=0,n=E(this),r=ot(i);while(e=r[t++])n.hasClass(e)?n.removeClass(e):n.addClass(e)}else void 0!==i&&"boolean"!==o||((e=it(this))&&Y.set(this,"__className__",e),this.setAttribute&&this.setAttribute("class",e||!1===i?"":Y.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&-1<(" "+rt(it(n))+" ").indexOf(t))return!0;return!1}});var at=/\r/g;E.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=b(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,E(this).val()):n)?t="":"number"==typeof t?t+="":Array.isArray(t)&&(t=E.map(t,function(e){return null==e?"":e+""})),(r=E.valHooks[this.type]||E.valHooks[this.nodeName.toLowerCase()])&&"set"in r&&void 0!==r.set(this,t,"value")||(this.value=t))})):t?(r=E.valHooks[t.type]||E.valHooks[t.nodeName.toLowerCase()])&&"get"in r&&void 0!==(e=r.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(at,""):null==e?"":e:void 0}}),E.extend({valHooks:{option:{get:function(e){var t=E.find.attr(e,"value");return null!=t?t:rt(E.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!S(n.parentNode,"optgroup"))){if(t=E(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=E.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<E.inArray(E.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),E.each(["radio","checkbox"],function(){E.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<E.inArray(E(e).val(),t)}},m.checkOn||(E.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),m.focusin="onfocusin"in g;var st=/^(?:focusinfocus|focusoutblur)$/,ut=function(e){e.stopPropagation()};E.extend(E.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f,d=[n||w],p=y.call(e,"type")?e.type:e,h=y.call(e,"namespace")?e.namespace.split("."):[];if(o=f=a=n=n||w,3!==n.nodeType&&8!==n.nodeType&&!st.test(p+E.event.triggered)&&(-1<p.indexOf(".")&&(p=(h=p.split(".")).shift(),h.sort()),u=p.indexOf(":")<0&&"on"+p,(e=e[E.expando]?e:new E.Event(p,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=h.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:E.makeArray(t,[e]),c=E.event.special[p]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!x(n)){for(s=c.delegateType||p,st.test(s+p)||(o=o.parentNode);o;o=o.parentNode)d.push(o),a=o;a===(n.ownerDocument||w)&&d.push(a.defaultView||a.parentWindow||g)}i=0;while((o=d[i++])&&!e.isPropagationStopped())f=o,e.type=1<i?s:c.bindType||p,(l=(Y.get(o,"events")||Object.create(null))[e.type]&&Y.get(o,"handle"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&X(o)&&(e.result=l.apply(o,t),!1===e.result&&e.preventDefault());return e.type=p,r||e.isDefaultPrevented()||c._default&&!1!==c._default.apply(d.pop(),t)||!X(n)||u&&b(n[p])&&!x(n)&&((a=n[u])&&(n[u]=null),E.event.triggered=p,e.isPropagationStopped()&&f.addEventListener(p,ut),n[p](),e.isPropagationStopped()&&f.removeEventListener(p,ut),E.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=E.extend(new E.Event,n,{type:e,isSimulated:!0});E.event.trigger(r,null,t)}}),E.fn.extend({trigger:function(e,t){return this.each(function(){E.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return E.event.trigger(e,t,n,!0)}}),m.focusin||E.each({focus:"focusin",blur:"focusout"},function(n,r){var i=function(e){E.event.simulate(r,e.target,E.event.fix(e))};E.event.special[r]={setup:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r);t||e.addEventListener(n,i,!0),Y.access(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r)-1;t?Y.access(e,r,t):(e.removeEventListener(n,i,!0),Y.remove(e,r))}}}),E.parseXML=function(e){var t,n;if(!e||"string"!=typeof e)return null;try{t=(new g.DOMParser).parseFromString(e,"text/xml")}catch(e){}return n=t&&t.getElementsByTagName("parsererror")[0],t&&!n||E.error("Invalid XML: "+(n?E.map(n.childNodes,function(e){return e.textContent}).join("\n"):e)),t};var lt,ct=/\[\]$/,ft=/\r?\n/g,dt=/^(?:submit|button|image|reset|file)$/i,pt=/^(?:input|select|textarea|keygen)/i;function ht(n,e,r,i){var t;if(Array.isArray(e))E.each(e,function(e,t){r||ct.test(n)?i(n,t):ht(n+"["+("object"==typeof t&&null!=t?e:"")+"]",t,r,i)});else if(r||"object"!==T(e))i(n,e);else for(t in e)ht(n+"["+t+"]",e[t],r,i)}E.param=function(e,t){var n,r=[],i=function(e,t){var n=b(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!E.isPlainObject(e))E.each(e,function(){i(this.name,this.value)});else for(n in e)ht(n,e[n],t,i);return r.join("&")},E.fn.extend({serialize:function(){return E.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=E.prop(this,"elements");return e?E.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!E(this).is(":disabled")&&pt.test(this.nodeName)&&!dt.test(e)&&(this.checked||!fe.test(e))}).map(function(e,t){var n=E(this).val();return null==n?null:Array.isArray(n)?E.map(n,function(e){return{name:t.name,value:e.replace(ft,"\r\n")}}):{name:t.name,value:n.replace(ft,"\r\n")}}).get()}}),E.fn.extend({wrapAll:function(e){var t;return this[0]&&(b(e)&&(e=e.call(this[0])),t=E(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return b(n)?this.each(function(e){E(this).wrapInner(n.call(this,e))}):this.each(function(){var e=E(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=b(t);return this.each(function(e){E(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not("body").each(function(){E(this).replaceWith(this.childNodes)}),this}}),E.expr.pseudos.hidden=function(e){return!E.expr.pseudos.visible(e)},E.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},m.createHTMLDocument=((lt=w.implementation.createHTMLDocument("").body).innerHTML="<form></form><form></form>",2===lt.childNodes.length),E.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(m.createHTMLDocument?((r=(t=w.implementation.createHTMLDocument("")).createElement("base")).href=w.location.href,t.head.appendChild(r)):t=w),o=!n&&[],(i=k.exec(e))?[t.createElement(i[1])]:(i=me([e],t,o),o&&o.length&&E(o).remove(),E.merge([],i.childNodes)));var r,i,o},E.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=E.css(e,"position"),c=E(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=E.css(e,"top"),u=E.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),b(t)&&(t=t.call(e,n,E.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},E.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){E.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===E.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===E.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=E(e).offset()).top+=E.css(e,"borderTopWidth",!0),i.left+=E.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-E.css(r,"marginTop",!0),left:t.left-i.left-E.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===E.css(e,"position"))e=e.offsetParent;return e||re})}}),E.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;E.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),E.each(["top","left"],function(e,n){E.cssHooks[n]=Me(m.pixelPosition,function(e,t){if(t)return t=Be(e,n),Pe.test(t)?E(e).position()[n]+"px":t})}),E.each({Height:"height",Width:"width"},function(a,s){E.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){E.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?E.css(e,t,i):E.style(e,t,n,i)},s,n?e:void 0,n)}})}),E.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),E.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){E.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}});var gt=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;E.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),b(e))return r=s.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(s.call(arguments)))}).guid=e.guid=e.guid||E.guid++,i},E.holdReady=function(e){e?E.readyWait++:E.ready(!0)},E.isArray=Array.isArray,E.parseJSON=JSON.parse,E.nodeName=S,E.isFunction=b,E.isWindow=x,E.camelCase=V,E.type=T,E.now=Date.now,E.isNumeric=function(e){var t=E.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},E.trim=function(e){return null==e?"":(e+"").replace(gt,"")},"function"==typeof define&&define.amd&&define("jquery",[],function(){return E});var vt=g.jQuery,yt=g.$;return E.noConflict=function(e){return g.$===E&&(g.$=yt),e&&g.jQuery===E&&(g.jQuery=vt),E},"undefined"==typeof e&&(g.jQuery=g.$=E),E});
resources/lock.png ADDED
resources/satellite.png ADDED
resources/search.png ADDED
resources/taxi.png ADDED
resources/vessel.png ADDED
runtime.txt ADDED
@@ -0,0 +1 @@
 
1
+ python-3.7.12
secure_app.py ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from hydralit import HydraApp
2
+ import hydralit_components as hc
3
+ import apps
4
+ import streamlit as st
5
+
6
+ #Only need to set these here as we are add controls outside of Hydralit, to customise a run Hydralit!
7
+ st.set_page_config(page_title='Secure Hydralit Data Explorer',page_icon="πŸ™",layout='wide',initial_sidebar_state='auto',)
8
+
9
+ if __name__ == '__main__':
10
+
11
+ #---ONLY HERE TO SHOW OPTIONS WITH HYDRALIT - NOT REQUIRED, use Hydralit constructor parameters.
12
+ st.write('Some options to change the way our Hydralit application looks and feels')
13
+ c1,c2,c3,c4,_ = st.columns([2,2,2,2,8])
14
+ hydralit_navbar = c1.checkbox('Use Hydralit Navbar',True)
15
+ sticky_navbar = c2.checkbox('Use Sticky Navbar',False)
16
+ animate_navbar = c3.checkbox('Use Animated Navbar',True)
17
+ hide_st = c4.checkbox('Hide Streamlit Markers',True)
18
+
19
+ over_theme = {'txc_inactive': '#FFFFFF'}
20
+ #this is the host application, we add children to it and that's it!
21
+ app = HydraApp(
22
+ title='Secure Hydralit Data Explorer',
23
+ favicon="πŸ™",
24
+ hide_streamlit_markers=hide_st,
25
+ #add a nice banner, this banner has been defined as 5 sections with spacing defined by the banner_spacing array below.
26
+ use_banner_images=["./resources/hydra.png",None,{'header':"<h1 style='text-align:center;padding: 0px 0px;color:grey;font-size:200%;'>Secure Hydralit Explorer</h1><br>"},None,"./resources/lock.png"],
27
+ banner_spacing=[5,30,60,30,5],
28
+ use_navbar=hydralit_navbar,
29
+ navbar_sticky=sticky_navbar,
30
+ navbar_animation=animate_navbar,
31
+ navbar_theme=over_theme
32
+ )
33
+
34
+ #Home button will be in the middle of the nav list now
35
+ app.add_app("Home", icon="🏠", app=apps.HomeApp(title='Home'),is_home=True)
36
+
37
+ #add all your application classes here
38
+ app.add_app("Cheat Sheet", icon="πŸ“š", app=apps.CheatApp(title="Cheat Sheet"))
39
+ app.add_app("Sequency Denoising",icon="πŸ”Š", app=apps.WalshApp(title="Sequency Denoising"))
40
+ app.add_app("Sequency (Secure)",icon="πŸ”ŠπŸ”’", app=apps.WalshAppSecure(title="Sequency (Secure)"))
41
+ app.add_app("Solar Mach", icon="πŸ›°οΈ", app=apps.SolarMach(title="Solar Mach"))
42
+ app.add_app("Spacy NLP", icon="⌨️", app=apps.SpacyNLP(title="Spacy NLP"))
43
+ app.add_app("Uber Pickups", icon="πŸš–", app=apps.UberNYC(title="Uber Pickups"))
44
+ app.add_app("Solar Mach", icon="πŸ›°οΈ", app=apps.SolarMach(title="Solar Mach"))
45
+ app.add_app("Loader Playground", icon="⏲️", app=apps.LoaderTestApp(title="Loader Playground"))
46
+ app.add_app("Cookie Cutter", icon="πŸͺ", app=apps.CookieCutterApp(title="Cookie Cutter"))
47
+
48
+ #we have added a sign-up app to demonstrate the ability to run an unsecure app
49
+ #only 1 unsecure app is allowed
50
+ app.add_app("Signup", icon="πŸ›°οΈ", app=apps.SignUpApp(title='Signup'), is_unsecure=True)
51
+
52
+ #we want to have secure access for this HydraApp, so we provide a login application
53
+ #optional logout label, can be blank for something nicer!
54
+ app.add_app("Login", apps.LoginApp(title='Login'),is_login=True)
55
+
56
+ #specify a custom loading app for a custom transition between apps, this includes a nice custom spinner
57
+ app.add_loader_app(apps.MyLoadingApp(delay=0))
58
+
59
+ #we can inject a method to be called everytime a user logs out
60
+ #---------------------------------------------------------------------
61
+ # @app.logout_callback
62
+ # def mylogout_cb():
63
+ # print('I was called from Hydralit at logout!')
64
+ #---------------------------------------------------------------------
65
+
66
+ #we can inject a method to be called everytime a user logs in
67
+ #---------------------------------------------------------------------
68
+ # @app.login_callback
69
+ # def mylogin_cb():
70
+ # print('I was called from Hydralit at login!')
71
+ #---------------------------------------------------------------------
72
+
73
+ #if we want to auto login a guest but still have a secure app, we can assign a guest account and go straight in
74
+ app.enable_guest_access()
75
+
76
+ #check user access level to determine what should be shown on the menu
77
+ user_access_level, username = app.check_access()
78
+
79
+ # If the menu is cluttered, just rearrange it into sections!
80
+ # completely optional, but if you have too many entries, you can make it nicer by using accordian menus
81
+ if user_access_level > 1:
82
+ complex_nav = {
83
+ 'Home': ['Home'],
84
+ 'Loader Playground': ['Loader Playground'],
85
+ 'Intro πŸ†': ['Cheat Sheet',"Solar Mach"],
86
+ 'Hotstepper πŸ”₯': ["Sequency Denoising","Sequency (Secure)"],
87
+ 'Clustering': ["Uber Pickups"],
88
+ 'NLP': ["Spacy NLP"],
89
+ 'Cookie Cutter': ['Cookie Cutter']
90
+ }
91
+ elif user_access_level == 1:
92
+ complex_nav = {
93
+ 'Home': ['Home'],
94
+ 'Loader Playground': ['Loader Playground'],
95
+ 'Intro πŸ†': ['Cheat Sheet',"Solar Mach"],
96
+ 'Hotstepper πŸ”₯': ["Sequency Denoising"],
97
+ 'Clustering': ["Uber Pickups"],
98
+ 'NLP': ["Spacy NLP"],
99
+ 'Cookie Cutter': ['Cookie Cutter']
100
+ }
101
+ else:
102
+ complex_nav = {
103
+ 'Home': ['Home'],
104
+ }
105
+
106
+
107
+ #and finally just the entire app and all the children.
108
+ app.run(complex_nav)
109
+
110
+
111
+ #print user movements and current login details used by Hydralit
112
+ #---------------------------------------------------------------------
113
+ # user_access_level, username = app.check_access()
114
+ # prev_app, curr_app = app.get_nav_transition()
115
+ # print(prev_app,'- >', curr_app)
116
+ # print(int(user_access_level),'- >', username)
117
+ # print('Other Nav after: ',app.session_state.other_nav_app)
118
+ #---------------------------------------------------------------------
119
+
setup.sh ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ mkdir -p ~/.streamlit/
2
+ echo "\
3
+ [general]\n\
4
+ email = \"{c6lculus8ntr0py@gmail.com}\"\n\
5
+ " > ~/.streamlit/credentials.toml
6
+ echo "\
7
+ [server]\n\
8
+ headless = true\n\
9
+ enableCORS=false\n\
10
+ port = $PORT\n\
11
+ " > ~/.streamlit/config.toml