Browse Source

Guided menu added (except last step)

pull/1/head
Benito Marcote 9 months ago
parent
commit
28bb0497c5
  1. 236
      app.py
  2. BIN
      assets/EVN.jpg
  3. 2050
      assets/bootstrap-grid.css
  4. 1
      assets/bootstrap-grid.css.map
  5. 7
      assets/bootstrap-grid.min.css
  6. 1
      assets/bootstrap-grid.min.css.map
  7. 330
      assets/bootstrap-reboot.css
  8. 1
      assets/bootstrap-reboot.css.map
  9. 8
      assets/bootstrap-reboot.min.css
  10. 1
      assets/bootstrap-reboot.min.css.map
  11. 6328
      assets/bootstrap.bundle.js
  12. 1
      assets/bootstrap.bundle.js.map
  13. 7
      assets/bootstrap.bundle.min.js
  14. 1
      assets/bootstrap.bundle.min.js.map
  15. 8975
      assets/bootstrap.css
  16. 1
      assets/bootstrap.css.map
  17. 3894
      assets/bootstrap.js
  18. 1
      assets/bootstrap.js.map
  19. 7
      assets/bootstrap.min.css
  20. 1
      assets/bootstrap.min.css.map
  21. 7
      assets/bootstrap.min.js
  22. 1
      assets/bootstrap.min.js.map
  23. 124
      assets/css/bootstrap-rtl-fix/_accordion.scss
  24. 55
      assets/css/bootstrap-rtl-fix/_alert.scss
  25. 29
      assets/css/bootstrap-rtl-fix/_badge.scss
  26. 29
      assets/css/bootstrap-rtl-fix/_breadcrumb.scss
  27. 140
      assets/css/bootstrap-rtl-fix/_button-group.scss
  28. 116
      assets/css/bootstrap-rtl-fix/_buttons.scss
  29. 214
      assets/css/bootstrap-rtl-fix/_card.scss
  30. 228
      assets/css/bootstrap-rtl-fix/_carousel.scss
  31. 40
      assets/css/bootstrap-rtl-fix/_close.scss
  32. 41
      assets/css/bootstrap-rtl-fix/_containers.scss
  33. 238
      assets/css/bootstrap-rtl-fix/_dropdown.scss
  34. 9
      assets/css/bootstrap-rtl-fix/_forms.scss
  35. 248
      assets/css/bootstrap-rtl-fix/_functions.scss
  36. 21
      assets/css/bootstrap-rtl-fix/_grid.scss
  37. 7
      assets/css/bootstrap-rtl-fix/_helpers.scss
  38. 41
      assets/css/bootstrap-rtl-fix/_images.scss
  39. 158
      assets/css/bootstrap-rtl-fix/_list-group.scss
  40. 41
      assets/css/bootstrap-rtl-fix/_mixins.scss
  41. 243
      assets/css/bootstrap-rtl-fix/_modal.scss
  42. 124
      assets/css/bootstrap-rtl-fix/_nav.scss
  43. 287
      assets/css/bootstrap-rtl-fix/_navbar.scss
  44. 78
      assets/css/bootstrap-rtl-fix/_pagination.scss
  45. 174
      assets/css/bootstrap-rtl-fix/_popover.scss
  46. 47
      assets/css/bootstrap-rtl-fix/_progress.scss
  47. 616
      assets/css/bootstrap-rtl-fix/_reboot.scss
  48. 16
      assets/css/bootstrap-rtl-fix/_root.scss
  49. 68
      assets/css/bootstrap-rtl-fix/_spinners.scss
  50. 149
      assets/css/bootstrap-rtl-fix/_tables.scss
  51. 50
      assets/css/bootstrap-rtl-fix/_toasts.scss
  52. 117
      assets/css/bootstrap-rtl-fix/_tooltip.scss
  53. 19
      assets/css/bootstrap-rtl-fix/_transitions.scss
  54. 102
      assets/css/bootstrap-rtl-fix/_type.scss
  55. 644
      assets/css/bootstrap-rtl-fix/_utilities.scss
  56. 1330
      assets/css/bootstrap-rtl-fix/_variables.scss
  57. 65
      assets/css/bootstrap-rtl-fix/bootstrap-grid.scss
  58. 15
      assets/css/bootstrap-rtl-fix/bootstrap-reboot.scss
  59. 17
      assets/css/bootstrap-rtl-fix/bootstrap-utilities.scss
  60. 51
      assets/css/bootstrap-rtl-fix/bootstrap.scss
  61. 61
      assets/css/bootstrap-rtl-fix/forms/_floating-labels.scss
  62. 155
      assets/css/bootstrap-rtl-fix/forms/_form-check.scss
  63. 223
      assets/css/bootstrap-rtl-fix/forms/_form-control.scss
  64. 95
      assets/css/bootstrap-rtl-fix/forms/_form-range.scss
  65. 69
      assets/css/bootstrap-rtl-fix/forms/_form-select.scss
  66. 11
      assets/css/bootstrap-rtl-fix/forms/_form-text.scss
  67. 124
      assets/css/bootstrap-rtl-fix/forms/_input-group.scss
  68. 36
      assets/css/bootstrap-rtl-fix/forms/_labels.scss
  69. 12
      assets/css/bootstrap-rtl-fix/forms/_validation.scss
  70. 3
      assets/css/bootstrap-rtl-fix/helpers/_clearfix.scss
  71. 16
      assets/css/bootstrap-rtl-fix/helpers/_colored-links.scss
  72. 30
      assets/css/bootstrap-rtl-fix/helpers/_position.scss
  73. 26
      assets/css/bootstrap-rtl-fix/helpers/_ratio.scss
  74. 15
      assets/css/bootstrap-rtl-fix/helpers/_stretched-link.scss
  75. 7
      assets/css/bootstrap-rtl-fix/helpers/_text-truncation.scss
  76. 8
      assets/css/bootstrap-rtl-fix/helpers/_visually-hidden.scss
  77. 9
      assets/css/bootstrap-rtl-fix/mixins/_alert.scss
  78. 75
      assets/css/bootstrap-rtl-fix/mixins/_border-radius.scss
  79. 18
      assets/css/bootstrap-rtl-fix/mixins/_box-shadow.scss
  80. 131
      assets/css/bootstrap-rtl-fix/mixins/_breakpoints.scss
  81. 138
      assets/css/bootstrap-rtl-fix/mixins/_buttons.scss
  82. 62
      assets/css/bootstrap-rtl-fix/mixins/_caret.scss
  83. 9
      assets/css/bootstrap-rtl-fix/mixins/_clearfix.scss
  84. 9
      assets/css/bootstrap-rtl-fix/mixins/_container.scss
  85. 10
      assets/css/bootstrap-rtl-fix/mixins/_deprecate.scss
  86. 117
      assets/css/bootstrap-rtl-fix/mixins/_forms.scss
  87. 76
      assets/css/bootstrap-rtl-fix/mixins/_gradients.scss
  88. 139
      assets/css/bootstrap-rtl-fix/mixins/_grid.scss
  89. 15
      assets/css/bootstrap-rtl-fix/mixins/_image.scss
  90. 22
      assets/css/bootstrap-rtl-fix/mixins/_list-group.scss
  91. 7
      assets/css/bootstrap-rtl-fix/mixins/_lists.scss
  92. 29
      assets/css/bootstrap-rtl-fix/mixins/_pagination.scss
  93. 17
      assets/css/bootstrap-rtl-fix/mixins/_reset-text.scss
  94. 6
      assets/css/bootstrap-rtl-fix/mixins/_resize.scss
  95. 21
      assets/css/bootstrap-rtl-fix/mixins/_table-variants.scss
  96. 8
      assets/css/bootstrap-rtl-fix/mixins/_text-truncate.scss
  97. 26
      assets/css/bootstrap-rtl-fix/mixins/_transition.scss
  98. 79
      assets/css/bootstrap-rtl-fix/mixins/_utilities.scss
  99. 28
      assets/css/bootstrap-rtl-fix/mixins/_visually-hidden.scss
  100. 45
      assets/css/bootstrap-rtl-fix/utilities/_api.scss

236
app.py

@ -71,7 +71,7 @@ sorted_networks = {'EVN': 'EVN: European VLBI Network', 'eMERLIN': 'eMERLIN (out
default_arrays = {'EVN': ['Ef', 'Hh', 'Jb2', 'Mc', 'Nt', 'Ur', 'On', 'Sr', 'T6', 'Tr',
'Ys', 'Wb', 'Bd', 'Sv', 'Zc', 'Ir'],
'e-EVN': ['Ef', 'Hh', 'Jb2', 'Mc', 'Nt', 'On', 'T6', 'Tr', 'Ys', 'Wb',
'Bd', 'Sv', 'Zc', 'Ir', 'Sr', 'Ur'],
'Bd', 'Sv', 'Zc', 'Ir', 'Sr'],
'eMERLIN': ['Cm', 'Kn', 'Pi', 'Da', 'De', 'Jb2'],
'LBA': ['ATCA', 'Pa', 'Mo', 'Ho', 'Cd', 'Td', 'Ww'],
'VLBA': ['Br', 'Fd', 'Hn', 'Kp', 'La', 'Mk', 'Nl', 'Ov', 'Pt', 'Sc'],
@ -84,6 +84,18 @@ default_arrays = {'EVN': ['Ef', 'Hh', 'Jb2', 'Mc', 'Nt', 'Ur', 'On', 'Sr', 'T6',
'GMVA': ['Ef', 'Mh', 'On', 'Ys', 'Pv', 'PdB', 'Br', 'Fd', 'Kp', 'La', 'Mk', 'Nl',
'Ov', 'Pt', 'Gb'],
'EHT': ['ALMA', 'Pv', 'LMT', 'PdB', 'SMA', 'JCMT', 'APEX', 'SMT', 'SPT']}
vlbi_networks_names = {'EVN': 'EVN: European VLBI Network',
'eMERLIN': 'e-MERLIN',
'LBA': 'LBA: Australian Long Baseline Array',
'VLBA': 'VLBA: Very Long Baseline Array',
'KVN': 'KVN: Korean VLBI Network',
# 'Global VLBI': 'Global VLBI (VLBA+EVN)',
'HSA': 'HSA: High Sensitivity Array',
'GMVA': 'GMVA: Global mm-VLBI Array',
'EHT': 'EHT: Event Horizon Telescope'}
#TODO: this will be included per station (but maybe it needs to remain):
default_datarates = {'EVN': 2048, 'e-EVN': 2048, 'eMERLIN': 4096, 'LBA': 1024, 'VLBA': 4096, 'KVN': 4096,
'Global VLBI': 2048, 'HSA': 2048, 'GMVA': 4096, 'EHT': 2**15}
@ -105,7 +117,7 @@ external_scripts = ["https://kit.fontawesome.com/69c65a0ab5.js"]
app = dash.Dash(__name__, title='EVN Observation Planner', external_scripts=external_scripts,
assets_folder=current_directory + '/assets/')
assets_folder=current_directory+'/assets/')
app.config.suppress_callback_exceptions = True # Avoids error messages for id's that haven't been loaded yet
server = app.server
@ -208,7 +220,7 @@ def update_sensitivity(obs):
def arrays_with_band(arrays, a_band):
"""Returns the given arrays that can observe the given band with at least two antennas.
"""Returns the arrays that can observe the given band with at least two antennas.
It excludes e-EVN if it is included in arrays.
Note that hardcoded is the detection of GMVA and EHT (only available at a given frequency).
@ -249,111 +261,12 @@ def arrays_with_band(arrays, a_band):
return ', '.join(tmp[:-1]) + ' and ' + tmp[-1]
def main_window_pick_band():
"""Initial window with the introduction to the EVN Observation Planner and the band selection.
"""
return [
html.Div(className='row justify-content-center',
children=html.Div(className='col-sm-6 justify-content-center',
children=[html.Div(className='justify-content-center',
children=[#html.H3("Welcome!"),
html.P(["The EVN Observation Planner allows you to plan observations with the ",
html.A(href="https://www.evlbi.org", children="European VLBI Network"),
" (EVN) and other Very Long Baseline Interferometry (VLBI) networks. "
"The EVN Observation Planner helps you to determine when your source "
"can be observed by the different antennas, and provides the expected "
"outcome of these observations, like the expected sensitivity or resolution."]),
html.H3("Select the observing band first"),
html.P(["Then you can continue to configure the rest of the observation. "
"Note that, in any case, you will still be able to change your selection "
"afterwards in case you want to compare different bands."])
], style={'text:align': 'justify !important'}),
html.Br(),
html.Div(className='justify-content-center', children=[html.Div(
dcc.Slider(id='pickband', min=0, max=len(fs.bands)-1,
value=tuple(fs.bands).index('18cm'), step=-1,
marks={i: fq for i,fq in enumerate(fs.bands)},
persistence=True, # tooltip={'always_visible': True, 'placement': 'top'},
updatemode='drag', included=False)), #html.Br(), html.Br(),
html.Div(id='pickband-label', className='row justify-content-center', children=''),
html.Div(className='row justify-content-center',
children=html.Button('Continue', id='pickband-button',
className='btn btn-primary btn-lg')),
html.Div(className='row justify-content-right col-1', children=[
html.Button('Skip', id='skip-button', className='btn btn-gray justify-content-right')
])
], style={'min-width': '33rem'})
])
)]
def main_window_pick_time():
"""Initial (second) window with the introduction to the EVN Observation Planner and
the option to pick a specific observing time or let the tool to find them.
"""
return [
html.Div(className='row justify-content-center',
children=html.Div(className='col-sm-6 justify-content-center',
children=[html.Div(className='justify-content-center',
children=[#html.H3("Welcome!"),
html.P(["The EVN Observation Planner allows you to plan observations with the ",
html.A(href="https://www.evlbi.org", children="European VLBI Network"),
" (EVN) and other Very Long Baseline Interferometry (VLBI) networks. "
"The EVN Observation Planner helps you to determine when your source "
"can be observed by the different antennas, and provides the expected "
"outcome of these observations, like the expected sensitivity or resolution."]),
html.H3("When to observe?"),
html.P(["You can pick a specific observing time or let the EVN Observation Planner "
"to find when your source can be observed by the antennas you will select. "
"Note that, in any case, you will still be able to change your selection "
"afterwards in case you want to compare different bands."])
], style={'text:align': 'justify !important'}),
html.Br(),
html.Div(className='justify-content-center', children=[html.Div(
dcc.Slider(id='pickband', min=0, max=len(fs.bands)-1,
value=tuple(fs.bands).index('18cm'), step=-1,
marks={i: fq for i,fq in enumerate(fs.bands)},
persistence=True, # tooltip={'always_visible': True, 'placement': 'top'},
updatemode='drag', included=False)), #html.Br(), html.Br(),
html.Div(id='pickband-label', className='row justify-content-center', children=''),
html.Div(className='row justify-content-center',
children=html.Button('Continue', id='pickband-button',
className='btn btn-primary btn-lg')),
html.Div(className='row justify-content-right col-1', children=[
html.Button('Skip', id='skip-button', className='btn btn-gray')
])
], style={'min-width': '33rem'})
])
)]
##################### This is the webpage layout
app.layout = html.Div([
html.Div(id='banner', className='navbar-brand d-flex p-3 shadow-sm', children=[
html.A(className='d-inline-block mr-md-auto', href="https://www.evlbi.org", children=[
html.Img(height='70px', src=app.get_asset_url("logo_evn.png"),
alt='European VLBI Network (EVN)',
className="d-inline-block align-top"),
]),
html.H2('EVN Observation Planner', className='d-inline-block align-middle mx-auto'),
html.A(className='d-inline-block ml-auto pull-right', href="https://www.jive.eu", children=[
html.Img(src=app.get_asset_url("logo_jive.png"), height='70px',
alt='Joinst Institute for VLBI ERIC (JIVE)')
])
]),
html.Div([html.Br()]),
html.Div(id='main-window', children=main_window_pick_band())])
@app.callback(Output('pickband-label', 'children'),
[Input('pickband', 'value')])
@app.callback(Output('initial-pickband-label', 'children'),
[Input('initial-band', 'value')])
def update_pickband_tooltip(a_wavelength):
a_band = tuple(fs.bands)[a_wavelength]
return [html.Div(dbc.Card(dbc.CardBody([
return [dbc.Card(dbc.CardBody([
html.H5([html.Img(height='30rem',
src=app.get_asset_url(f"waves-{a_band.replace('.', '_')}.svg"),
alt='Band: ', className='d-inline-block'),
@ -366,29 +279,90 @@ def update_pickband_tooltip(a_wavelength):
html.Span("Frequency: ", style={'color': '#888888'}),
f"{fs.bands[a_band].split('(')[1].split('or')[1].replace(')', '').strip()}.",
html.Br(),
html.Span(f"Can be observed with the {arrays_with_band(default_arrays, a_band)}.",
html.Span(html.Small(f"Can be observed with the {arrays_with_band(default_arrays, a_band)}."),
style={'color': '#888888'})
], className="card-text"),
]), className="col-sm-3 justify-content-center",
style={'margin-top': '2rem', 'margin-bottom': '2rem'}), className='justify-content-center'
)
]), className="col-sm-3 my-2 shadow-1-strong border border-primary")
]
@app.callback([Output('initial-timeselection-div-guess', 'hidden'),
Output('initial-timeselection-div-epoch', 'hidden')],
[Input('initial-timeselection', 'value')])
def type_time_selection(time_selection_selected):
"""Modifies the hidden message related to the two options about how to pick the observing time.
"""
return [time_selection_selected, not time_selection_selected]
@app.callback(Output('main-window', 'children'),
[Input('skip-button', 'n_clicks'),
Input('pickband-button', 'n_clicks')],
[State('pickband', 'value')])
def skip_intro_choices(skip_clicks, pickband_clicks, a_wavelength):
if (skip_clicks is None) and (pickband_clicks is None):
return dash.no_update
elif skip_clicks is not None:
[Input('button-initial-wizard', 'n_clicks'),
Input('button-initial-expert', 'n_clicks'),
Input('button-pickband', 'n_clicks'),
Input('button-picknetwork', 'n_clicks'),
Input('button-picktimes', 'n_clicks'),
Input('button-mode-continuum', 'n_clicks'),
Input('button-mode-line', 'n_clicks')],
[State('initial-band', 'value'),
State('initial-array', 'value'),
State('initial-timeselection', 'value'), # True if date are provided, False if guessing
State('starttime', 'date'),
State('starthour', 'value'),
State('duration', 'value')
])
def skip_intro_choices(clicks_wizard, clicks_expert, clicks_pickband, clicks_picknetwork, clicks_picktimes,
clicks_continuum, clicks_line,
a_wavelength, a_array, time_selection, starttime, starthour, obs_duration):
if clicks_expert is not None:
return main_page(None)
elif pickband_clicks is not None:
return main_page(a_wavelength)
elif clicks_wizard is not None:
return initial_page('band')
elif clicks_pickband is not None:
return initial_page('network')
elif clicks_picknetwork is not None:
return initial_page('time')
elif clicks_picktimes is not None:
#TODO: if dates are provided, all date/time/dur must be provided
return initial_page('mode')
elif clicks_continuum is not None:
return compute_observation(n_clicks, band, starttime, starthour, duration, source, onsourcetime,
datarate, subbands, channels, pols, inttime, guest_time, selected_tab, *ants)
elif clicks_line is not None:
return dash.no_update
else:
return dash.no_update
def initial_page(choice_card):
"""Initial window with the introduction to the EVN Observation Planner and the band selection.
"""
return [
html.Div(className='row justify-content-center',
children=html.Div(className='col-sm-6 justify-content-center',
children=[html.Div(className='justify-content-center',
children=[#html.H3("Welcome!"),
html.P(["The EVN Observation Planner allows you to plan observations with the ",
html.A(href="https://www.evlbi.org", children="European VLBI Network"),
" (EVN) and other Very Long Baseline Interferometry (VLBI) networks. "
"The EVN Observation Planner helps you to determine when your source "
"can be observed by the different antennas, and provides the expected "
"outcome of these observations, like the expected sensitivity or resolution."]),
html.Br(),
*[
html.Div(hidden=False if choice_card == 'choice' else True,
children=ge.initial_window_start(app)),
html.Div(hidden=False if choice_card == 'band' else True,
children=ge.initial_window_pick_band()),
html.Div(hidden=False if choice_card == 'network' else True,
children=ge.initial_window_pick_network(vlbi_networks_names)),
html.Div(hidden=False if choice_card == 'time' else True,
children=ge.initial_window_pick_time()),
html.Div(hidden=False if choice_card == 'mode' else True,
children=ge.initial_window_pick_mode(app)),
],
], style={'text:align': 'justify !important'})
])
)] #, *main_page(None, True)]
@ -474,7 +448,7 @@ def main_page(a_wavelength):
])]))
]),
]),
dbc.Tab(label='Guest Times', id='tab-guest-times', tabClassName='tab-for-card', children=[
dbc.Tab(label='Guess Times', id='tab-guess-times', tabClassName='tab-for-card', children=[
html.Div(className='form-group', children=[
dbc.Card(className='card-no-left-border', children=dbc.CardBody([
html.P("Choose this option if you just want to find out when your source "
@ -717,7 +691,7 @@ def main_page(a_wavelength):
@app.callback([Output('tab-pick-epoch', 'label'),
Output('tab-guest-times', 'label')],
Output('tab-guess-times', 'label')],
[Input('guest-times', 'value')])
def update_tab_time_labels(guest_time):
"""Updates the labels in the tabs where the user can either pick a specific observing
@ -763,6 +737,7 @@ def select_antennas(selected_band, selected_networks, is_eEVN):
"""Given a selected band and selected default networks, it selects the associated
antennas from the antenna list.
"""
print(selected_band, selected_networks, is_eEVN)
selected_antennas = []
if is_eEVN:
selected_antennas = [ant for ant in default_arrays['e-EVN'] \
@ -1102,6 +1077,25 @@ def get_fig_dirty_map(obs):
pass
##################### This is the webpage layout
app.layout = html.Div([
html.Div(id='banner', className='navbar-brand d-flex p-3 shadow-sm', children=[
html.A(className='d-inline-block mr-md-auto', href="https://www.evlbi.org", children=[
html.Img(height='70px', src=app.get_asset_url("logo_evn.png"),
alt='European VLBI Network (EVN)',
className="d-inline-block align-top"),
]),
html.H2('EVN Observation Planner', className='d-inline-block align-middle mx-auto'),
html.A(className='d-inline-block ml-auto pull-right', href="https://www.jive.eu", children=[
html.Img(src=app.get_asset_url("logo_jive.png"), height='70px',
alt='Joinst Institute for VLBI ERIC (JIVE)')
])
]),
html.Div([html.Br()]),
html.Div(id='main-window', children=initial_page('choice'))])
if __name__ == '__main__':

BIN
assets/EVN.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 MiB

2050
assets/bootstrap-grid.css

File diff suppressed because it is too large

1
assets/bootstrap-grid.css.map

File diff suppressed because one or more lines are too long

7
assets/bootstrap-grid.min.css

File diff suppressed because one or more lines are too long

1
assets/bootstrap-grid.min.css.map

File diff suppressed because one or more lines are too long

330
assets/bootstrap-reboot.css

@ -1,330 +0,0 @@
/*!
* Bootstrap Reboot v4.0.0 (https://getbootstrap.com)
* Copyright 2011-2018 The Bootstrap Authors
* Copyright 2011-2018 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
font-family: sans-serif;
line-height: 1.15;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
-ms-overflow-style: scrollbar;
-webkit-tap-highlight-color: transparent;
}
@-ms-viewport {
width: device-width;
}
article, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section {
display: block;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
background-color: #fff;
}
[tabindex="-1"]:focus {
outline: 0 !important;
}
hr {
box-sizing: content-box;
height: 0;
overflow: visible;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: 0.5rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-original-title] {
text-decoration: underline;
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
border-bottom: 0;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: .5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
dfn {
font-style: italic;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 80%;
}
sub,
sup {
position: relative;
font-size: 75%;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -.25em;
}
sup {
top: -.5em;
}
a {
color: #007bff;
text-decoration: none;
background-color: transparent;
-webkit-text-decoration-skip: objects;
}
a:hover {
color: #0056b3;
text-decoration: underline;
}
a:not([href]):not([tabindex]) {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):focus {
outline: 0;
}
pre,
code,
kbd,
samp {
font-family: monospace, monospace;
font-size: 1em;
}
pre {
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
-ms-overflow-style: scrollbar;
}
figure {
margin: 0 0 1rem;
}
img {
vertical-align: middle;
border-style: none;
}
svg:not(:root) {
overflow: hidden;
}
table {
border-collapse: collapse;
}
caption {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
color: #6c757d;
text-align: left;
caption-side: bottom;
}
th {
text-align: inherit;
}
label {
display: inline-block;
margin-bottom: .5rem;
}
button {
border-radius: 0;
}
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
button,
html [type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
padding: 0;
border-style: none;
}
input[type="radio"],
input[type="checkbox"] {
box-sizing: border-box;
padding: 0;
}
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
-webkit-appearance: listbox;
}
textarea {
overflow: auto;
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
display: block;
width: 100%;
max-width: 100%;
padding: 0;
margin-bottom: .5rem;
font-size: 1.5rem;
line-height: inherit;
color: inherit;
white-space: normal;
}
progress {
vertical-align: baseline;
}
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
outline-offset: -2px;
-webkit-appearance: none;
}
[type="search"]::-webkit-search-cancel-button,
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
summary {
display: list-item;
cursor: pointer;
}
template {
display: none;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */

1
assets/bootstrap-reboot.css.map

File diff suppressed because one or more lines are too long

8
assets/bootstrap-reboot.min.css

@ -1,8 +0,0 @@
/*!
* Bootstrap Reboot v4.0.0 (https://getbootstrap.com)
* Copyright 2011-2018 The Bootstrap Authors
* Copyright 2011-2018 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg:not(:root){overflow:hidden}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}
/*# sourceMappingURL=bootstrap-reboot.min.css.map */

1
assets/bootstrap-reboot.min.css.map

File diff suppressed because one or more lines are too long

6328
assets/bootstrap.bundle.js

File diff suppressed because it is too large

1
assets/bootstrap.bundle.js.map

File diff suppressed because one or more lines are too long

7
assets/bootstrap.bundle.min.js

File diff suppressed because one or more lines are too long

1
assets/bootstrap.bundle.min.js.map

File diff suppressed because one or more lines are too long

8975
assets/bootstrap.css

File diff suppressed because it is too large

1
assets/bootstrap.css.map

File diff suppressed because one or more lines are too long

3894
assets/bootstrap.js

File diff suppressed because it is too large

1
assets/bootstrap.js.map

File diff suppressed because one or more lines are too long

7
assets/bootstrap.min.css

File diff suppressed because one or more lines are too long

1
assets/bootstrap.min.css.map

File diff suppressed because one or more lines are too long

7
assets/bootstrap.min.js

File diff suppressed because one or more lines are too long

1
assets/bootstrap.min.js.map

File diff suppressed because one or more lines are too long

124
assets/css/bootstrap-rtl-fix/_accordion.scss

@ -0,0 +1,124 @@
//
// Base styles
//
.accordion-button {
position: relative;
display: flex;
align-items: center;
width: 100%;
padding: $accordion-button-padding-y $accordion-button-padding-x;
@include font-size($font-size-base);
color: $accordion-button-color;
background-color: $accordion-button-bg;
border: $accordion-border-width solid $accordion-border-color;
@include border-radius(0);
overflow-anchor: none;
@include transition($accordion-transition);
&.collapsed {
border-bottom-width: 0;
}
&:not(.collapsed) {
color: $accordion-button-active-color;
background-color: $accordion-button-active-bg;
&::after {
background-image: escape-svg($accordion-button-active-icon);
transform: $accordion-icon-transform;
}
}
// Accordion icon
&::after {
flex-shrink: 0;
width: $accordion-icon-width;
height: $accordion-icon-width;
margin-left: auto;
content: '';
background-image: escape-svg($accordion-button-icon);
background-repeat: no-repeat;
background-size: $accordion-icon-width;
@include transition($accordion-icon-transition);
}
&:hover {
z-index: 2;
}
&:focus {
z-index: 3;
border-color: $accordion-button-focus-border-color;
outline: 0;
box-shadow: $accordion-button-focus-box-shadow;
}
}
.accordion-header {
margin-bottom: 0;
}
.accordion-item {
&:first-of-type {
.accordion-button {
@include border-top-radius($accordion-border-radius);
}
}
&:last-of-type {
.accordion-button {
// Only set a border-radius on the last item if the accordion is collapsed
&.collapsed {
border-bottom-width: $accordion-border-width;
@include border-bottom-radius($accordion-border-radius);
}
}
.accordion-collapse {
border-bottom-width: $accordion-border-width;
@include border-bottom-radius($accordion-border-radius);
}
}
}
.accordion-collapse {
border: solid $accordion-border-color;
border-width: 0 $accordion-border-width;
}
.accordion-body {
padding: $accordion-body-padding-y $accordion-body-padding-x;
}
// Flush accordion items
//
// Remove borders and border-radius to keep accordion items edge-to-edge.
.accordion-flush {
.accordion-button {
border-right: 0;
border-left: 0;
@include border-radius(0);
}
.accordion-collapse {
border-width: 0;
}
.accordion-item {
&:first-of-type {
.accordion-button {
border-top-width: 0;
@include border-top-radius(0);
}
}
&:last-of-type {
.accordion-button.collapsed {
border-bottom-width: 0;
@include border-bottom-radius(0);
}
}
}
}

55
assets/css/bootstrap-rtl-fix/_alert.scss

@ -0,0 +1,55 @@
//
// Base styles
//
.alert {
position: relative;
padding: $alert-padding-y $alert-padding-x;
margin-bottom: $alert-margin-bottom;
border: $alert-border-width solid transparent;
@include border-radius($alert-border-radius);
}
// Headings for larger alerts
.alert-heading {
// Specified to prevent conflicts of changing $headings-color
color: inherit;
}
// Provide class for links that match alerts
.alert-link {
font-weight: $alert-link-font-weight;
}
// Dismissible alerts
//
// Expand the right padding and account for the close button's positioning.
.alert-dismissible {
padding-right: $alert-dismissible-padding-r;
// Adjust close link position
.btn-close {
position: absolute;
top: 0;
right: 0;
z-index: $stretched-link-z-index + 1;
padding: $alert-padding-y * 1.25 $alert-padding-x;
}
}
// scss-docs-start alert-modifiers
// Generate contextual modifier classes for colorizing the alert.
@each $state, $value in $theme-colors {
$background: shift-color($value, $alert-bg-scale);
$border: shift-color($value, $alert-border-scale);
$color: shift-color($value, $alert-color-scale);
@if (contrast-ratio($background, $color) < $min-contrast-ratio) {
$color: mix($value, color-contrast($background), abs($alert-color-scale));
}
.alert-#{$state} {
@include alert-variant($background, $border, $color);
}
}
// scss-docs-end alert-modifiers

29
assets/css/bootstrap-rtl-fix/_badge.scss

@ -0,0 +1,29 @@
// Base class
//
// Requires one of the contextual, color modifier classes for `color` and
// `background-color`.
.badge {
display: inline-block;
padding: $badge-padding-y $badge-padding-x;
@include font-size($badge-font-size);
font-weight: $badge-font-weight;
line-height: 1;
color: $badge-color;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
@include border-radius($badge-border-radius);
@include gradient-bg();
// Empty badges collapse automatically
&:empty {
display: none;
}
}
// Quick fix for badges in buttons
.btn .badge {
position: relative;
top: -1px;
}

29
assets/css/bootstrap-rtl-fix/_breadcrumb.scss

@ -0,0 +1,29 @@
.breadcrumb {
display: flex;
flex-wrap: wrap;
padding: $breadcrumb-padding-y $breadcrumb-padding-x;
margin-bottom: $breadcrumb-margin-bottom;
@include font-size($breadcrumb-font-size);
list-style: none;
background-color: $breadcrumb-bg;
@include border-radius($breadcrumb-border-radius);
}
.breadcrumb-item {
// The separator between breadcrumbs (by default, a forward-slash: "/")
+ .breadcrumb-item {
padding-left: $breadcrumb-item-padding-x;
&::before {
float: left; // Suppress inline spacings and underlining of the separator
padding-right: $breadcrumb-item-padding-x;
color: $breadcrumb-divider-color;
content: var(--#{$variable-prefix}breadcrumb-divider, escape-svg($breadcrumb-divider)) #{'/*!rtl:'}
var(--#{$variable-prefix}breadcrumb-divider, escape-svg($breadcrumb-divider-flipped)) #{'*/'};
}
}
&.active {
color: $breadcrumb-active-color;
}
}

140
assets/css/bootstrap-rtl-fix/_button-group.scss

@ -0,0 +1,140 @@
// Make the div behave like a button
.btn-group,
.btn-group-vertical {
position: relative;
display: inline-flex;
vertical-align: middle; // match .btn alignment given font-size hack above
> .btn {
position: relative;
flex: 1 1 auto;
}
// Bring the hover, focused, and "active" buttons to the front to overlay
// the borders properly
> .btn-check:checked + .btn,
> .btn-check:focus + .btn,
> .btn:hover,
> .btn:focus,
> .btn:active,
> .btn.active {
z-index: 1;
}
}
// Optional: Group multiple button groups together for a toolbar
.btn-toolbar {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
.input-group {
width: auto;
}
}
.btn-group {
// Prevent double borders when buttons are next to each other
> .btn:not(:first-child),
> .btn-group:not(:first-child) {
margin-left: -$btn-border-width;
}
// Reset rounded corners
> .btn:not(:last-child):not(.dropdown-toggle),
> .btn-group:not(:last-child) > .btn {
@include border-end-radius(0);
}
// The left radius should be 0 if the button is:
// - the "third or more" child
// - the second child and the previous element isn't `.btn-check` (making it the first child visually)
// - part of a btn-group which isn't the first child
> .btn:nth-child(n + 3),
> :not(.btn-check) + .btn,
> .btn-group:not(:first-child) > .btn {
@include border-start-radius(0);
}
}
// Sizing
//
// Remix the default button sizing classes into new ones for easier manipulation.
.btn-group-sm > .btn {
@extend .btn-sm;
}
.btn-group-lg > .btn {
@extend .btn-lg;
}
//
// Split button dropdowns
//
.dropdown-toggle-split {
padding-right: $btn-padding-x * 0.75;
padding-left: $btn-padding-x * 0.75;
&::after,
.dropup &::after,
.dropend &::after {
margin-left: 0;
}
.dropstart &::before {
margin-right: 0;
}
}
.btn-sm + .dropdown-toggle-split {
padding-right: $btn-padding-x-sm * 0.75;
padding-left: $btn-padding-x-sm * 0.75;
}
.btn-lg + .dropdown-toggle-split {
padding-right: $btn-padding-x-lg * 0.75;
padding-left: $btn-padding-x-lg * 0.75;
}
// The clickable button for toggling the menu
// Set the same inset shadow as the :active state
.btn-group.show .dropdown-toggle {
@include box-shadow($btn-active-box-shadow);
// Show no shadow for `.btn-link` since it has no other button styles.
&.btn-link {
@include box-shadow(none);
}
}
//
// Vertical button groups
//
.btn-group-vertical {
flex-direction: column;
align-items: flex-start;
justify-content: center;
> .btn,
> .btn-group {
width: 100%;
}
> .btn:not(:first-child),
> .btn-group:not(:first-child) {
margin-top: -$btn-border-width;
}
// Reset rounded corners
> .btn:not(:last-child):not(.dropdown-toggle),
> .btn-group:not(:last-child) > .btn {
@include border-bottom-radius(0);
}
> .btn ~ .btn,
> .btn-group:not(:first-child) > .btn {
@include border-top-radius(0);
}
}

116
assets/css/bootstrap-rtl-fix/_buttons.scss

@ -0,0 +1,116 @@
//
// Base styles
//
.btn {
display: inline-block;
font-family: $btn-font-family;
font-weight: $btn-font-weight;
line-height: $btn-line-height;
color: $body-color;
text-align: center;
text-decoration: if($link-decoration == none, null, none);
white-space: $btn-white-space;
vertical-align: middle;
cursor: if($enable-button-pointers, pointer, null);
user-select: none;
background-color: transparent;
border: $btn-border-width solid transparent;
@include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-border-radius);
@include transition($btn-transition);
&:hover {
color: $body-color;
text-decoration: if($link-hover-decoration == underline, none, null);
}
.btn-check:focus + &,
&:focus {
outline: 0;
box-shadow: $btn-focus-box-shadow;
}
.btn-check:checked + &,
.btn-check:active + &,
&:active,
&.active {
@include box-shadow($btn-active-box-shadow);
&:focus {
@include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow);
}
}
&:disabled,
&.disabled,
fieldset:disabled & {
pointer-events: none;
opacity: $btn-disabled-opacity;
@include box-shadow(none);
}
}
//
// Alternate buttons
//
@each $color, $value in $theme-colors {
.btn-#{$color} {
@include button-variant($value, $value);
}
}
@each $color, $value in $theme-colors {
.btn-outline-#{$color} {
@include button-outline-variant($value);
}
}
//
// Link buttons
//
// Make a button look and behave like a link
.btn-link {
font-weight: $font-weight-normal;
color: $btn-link-color;
text-decoration: $link-decoration;
&:hover {
color: $btn-link-hover-color;
text-decoration: $link-hover-decoration;
}
&:focus {
text-decoration: $link-hover-decoration;
}
&:disabled,
&.disabled {
color: $btn-link-disabled-color;
}
// No need for an active state here
}
//
// Button Sizes
//
.btn-lg {
@include button-size(
$btn-padding-y-lg,
$btn-padding-x-lg,
$btn-font-size-lg,
$btn-border-radius-lg
);
}
.btn-sm {
@include button-size(
$btn-padding-y-sm,
$btn-padding-x-sm,
$btn-font-size-sm,
$btn-border-radius-sm
);
}

214
assets/css/bootstrap-rtl-fix/_card.scss

@ -0,0 +1,214 @@
//
// Base styles
//
.card {
position: relative;
display: flex;
flex-direction: column;
min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106
height: $card-height;
word-wrap: break-word;
background-color: $card-bg;
background-clip: border-box;
border: $card-border-width solid $card-border-color;
@include border-radius($card-border-radius);
> hr {
margin-right: 0;
margin-left: 0;
}
> .list-group {
border-top: inherit;
border-bottom: inherit;
&:first-child {
border-top-width: 0;
@include border-top-radius($card-inner-border-radius);
}
&:last-child {
border-bottom-width: 0;
@include border-bottom-radius($card-inner-border-radius);
}
}
// Due to specificity of the above selector (`.card > .list-group`), we must
// use a child selector here to prevent double borders.
> .card-header + .list-group,
> .list-group + .card-footer {
border-top: 0;
}
}
.card-body {
// Enable `flex-grow: 1` for decks and groups so that card blocks take up
// as much space as possible, ensuring footers are aligned to the bottom.
flex: 1 1 auto;
padding: $card-spacer-y $card-spacer-x;
color: $card-color;
}
.card-title {
margin-bottom: $card-title-spacer-y;
}
.card-subtitle {
margin-top: -$card-title-spacer-y / 2;
margin-bottom: 0;
}
.card-text:last-child {
margin-bottom: 0;
}
.card-link {
&:hover {
text-decoration: none;
}
+ .card-link {
/*!rtl:ignore*/
margin-left: 5px;
}
}
//
// Optional textual caps
//
.card-header {
padding: $card-cap-padding-y $card-cap-padding-x;
margin-bottom: 0; // Removes the default margin-bottom of <hN>
color: $card-cap-color;
background-color: $card-cap-bg;
border-bottom: $card-border-width solid $card-border-color;
&:first-child {
@include border-radius($card-inner-border-radius $card-inner-border-radius 0 0);
}
}
.card-footer {
padding: $card-cap-padding-y $card-cap-padding-x;
color: $card-cap-color;
background-color: $card-cap-bg;
border-top: $card-border-width solid $card-border-color;
&:last-child {
@include border-radius(0 0 $card-inner-border-radius $card-inner-border-radius);
}
}
//
// Header navs
//
.card-header-tabs {
margin-right: -$card-cap-padding-x / 2;
margin-bottom: -$card-cap-padding-y;
margin-left: -$card-cap-padding-x / 2;
border-bottom: 0;
@if $nav-tabs-link-active-bg != $card-bg {
.nav-link.active {
background-color: $card-bg;
border-bottom-color: $card-bg;
}
}
}
.card-header-pills {
margin-right: -$card-cap-padding-x / 2;
margin-left: -$card-cap-padding-x / 2;
}
// Card image
.card-img-overlay {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
padding: $card-img-overlay-padding;
@include border-radius($card-inner-border-radius);
}
.card-img,
.card-img-top,
.card-img-bottom {
width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch
}
.card-img,
.card-img-top {
@include border-top-radius($card-inner-border-radius);
}
.card-img,
.card-img-bottom {
@include border-bottom-radius($card-inner-border-radius);
}
//
// Card groups
//
.card-group {
// The child selector allows nested `.card` within `.card-group`
// to display properly.
> .card {
margin-bottom: $card-group-margin;
}
@include media-breakpoint-up(sm) {
display: flex;
flex-flow: row wrap;
// The child selector allows nested `.card` within `.card-group`
// to display properly.
> .card {
// Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4
flex: 1 0 0%;
margin-bottom: 0;
+ .card {
margin-left: 0;
border-left: 0;
}
// Handle rounded corners
@if $enable-rounded {
&:not(:last-child) {
@include border-end-radius(0);
.card-img-top,
.card-header {
// stylelint-disable-next-line property-disallowed-list
border-top-right-radius: 0;
}
.card-img-bottom,
.card-footer {
// stylelint-disable-next-line property-disallowed-list
border-bottom-right-radius: 0;
}
}
&:not(:first-child) {
@include border-start-radius(0);
.card-img-top,
.card-header {
// stylelint-disable-next-line property-disallowed-list
border-top-left-radius: 0;
}
.card-img-bottom,
.card-footer {
// stylelint-disable-next-line property-disallowed-list
border-bottom-left-radius: 0;
}
}
}
}
}
}

228
assets/css/bootstrap-rtl-fix/_carousel.scss

@ -0,0 +1,228 @@
// Notes on the classes:
//
// 1. .carousel.pointer-event should ideally be pan-y (to allow for users to scroll vertically)
// even when their scroll action started on a carousel, but for compatibility (with Firefox)