Merge branch 'develop' into feature/django2
This commit is contained in:
192
requirements_win.txt
Normal file
192
requirements_win.txt
Normal file
@@ -0,0 +1,192 @@
|
||||
amqp==2.4.2
|
||||
apipkg==1.5
|
||||
appdirs==1.4.3
|
||||
arcgis==1.6.0
|
||||
arrow==0.13.1
|
||||
asn1crypto==0.24.0
|
||||
atomicwrites==1.3.0
|
||||
attrs==19.1.0
|
||||
backcall==0.1.0
|
||||
beautifulsoup4==4.7.1
|
||||
billiard==3.5.0.5
|
||||
bleach==3.1.0
|
||||
bokeh==1.0.4
|
||||
boto==2.49.0
|
||||
braintree==3.51.0
|
||||
cairocffi==1.0.2
|
||||
celery==4.2.2
|
||||
certifi==2019.3.9
|
||||
cffi==1.12.2
|
||||
chardet==3.0.4
|
||||
Click==7.0
|
||||
colorama==0.4.1
|
||||
colorclass==2.2.0
|
||||
cookies==2.2.1
|
||||
coreapi==2.3.3
|
||||
coreschema==0.0.4
|
||||
coverage==4.5.3
|
||||
cryptography==2.6.1
|
||||
cycler==0.10.0
|
||||
dask==1.1.4
|
||||
decorator==4.4.0
|
||||
defusedxml==0.5.0
|
||||
Django==1.9.5
|
||||
django-analytical==2.5.0
|
||||
django-async-messages==0.3.1
|
||||
django-braces==1.13.0
|
||||
django-classy-tags==0.8.0
|
||||
django-cookie-law==2.0.1
|
||||
django-cors-headers==2.4.0
|
||||
django-countries==5.3.3
|
||||
django-datetime-widget==0.9.3
|
||||
django-debug-toolbar==1.4
|
||||
django-extensions==2.1.6
|
||||
django-htmlmin==0.10.0
|
||||
django-leaflet==0.24.0
|
||||
django-mailbox==4.7.1
|
||||
django-oauth-toolkit==0.10.0
|
||||
django-oauth2-provider==0.2.6.1
|
||||
django-rest-framework==0.1.0
|
||||
django-rest-swagger==2.2.0
|
||||
django-rq==1.3.0
|
||||
django-rq-dashboard==0.3.3
|
||||
django-ses==0.8.10
|
||||
django-shell-plus==1.1.7
|
||||
django-social-share==1.3.2
|
||||
django-suit==0.2.26
|
||||
django-suit-rq==1.0.1
|
||||
django-tz-detect==0.2.9
|
||||
djangorestframework==3.5.4
|
||||
docopt==0.6.2
|
||||
docutils==0.14
|
||||
entrypoints==0.3
|
||||
execnet==1.5.0
|
||||
factory-boy==2.11.1
|
||||
Faker==1.0.4
|
||||
fitparse==1.1.0
|
||||
future==0.17.1
|
||||
GDAL==2.3.3
|
||||
geocoder==1.38.1
|
||||
holoviews==1.11.3
|
||||
html5lib==1.0.1
|
||||
htmlmin==0.1.12
|
||||
HTMLParser==0.0.2
|
||||
httplib2==0.12.1
|
||||
icalendar==4.0.3
|
||||
idna==2.8
|
||||
image==1.5.27
|
||||
importlib-resources==1.0.2
|
||||
ipykernel==5.1.0
|
||||
ipython==7.3.0
|
||||
ipython-genutils==0.2.0
|
||||
ipywidgets==7.4.2
|
||||
iso8601==0.1.12
|
||||
isodate==0.6.0
|
||||
itypes==1.1.0
|
||||
jedi==0.13.3
|
||||
jeepney==0.4
|
||||
Jinja2==2.10
|
||||
jsonschema==3.0.1
|
||||
jupyter==1.0.0
|
||||
jupyter-client==5.2.4
|
||||
jupyter-console==6.0.0
|
||||
jupyter-core==4.4.0
|
||||
jupyterlab==0.35.4
|
||||
jupyterlab-server==0.2.0
|
||||
keyring==18.0.0
|
||||
kiwisolver==1.0.1
|
||||
kombu==4.3.0
|
||||
lxml==4.3.2
|
||||
Markdown==3.0.1
|
||||
MarkupSafe==1.1.1
|
||||
matplotlib==3.0.3
|
||||
MiniMockTest==0.5
|
||||
mistune==0.8.4
|
||||
mock==2.0.0
|
||||
more-itertools==6.0.0
|
||||
mpld3==0.3
|
||||
nbconvert==5.4.1
|
||||
nbformat==4.4.0
|
||||
nose==1.3.7
|
||||
nose-parameterized==0.6.0
|
||||
notebook==5.7.6
|
||||
numpy==1.16.2
|
||||
oauth2==1.9.0.post1
|
||||
oauthlib==1.0.3
|
||||
openapi-codec==1.3.2
|
||||
packaging==19.0
|
||||
pandas==0.24.2
|
||||
pandocfilters==1.4.2
|
||||
param==1.8.2
|
||||
parso==0.3.4
|
||||
pathspec==0.5.9
|
||||
pbr==5.1.3
|
||||
pexpect==4.6.0
|
||||
pickleshare==0.7.5
|
||||
Pillow==5.4.1
|
||||
pip-upgrader==1.4.6
|
||||
pluggy==0.9.0
|
||||
prometheus-client==0.6.0
|
||||
prompt-toolkit==2.0.9
|
||||
ptyprocess==0.6.0
|
||||
py==1.8.0
|
||||
pycparser==2.19
|
||||
Pygments==2.3.1
|
||||
pyparsing==2.3.1
|
||||
pyrsistent==0.14.11
|
||||
pyshp==2.1.0
|
||||
pytest==4.3.1
|
||||
pytest-django==3.4.8
|
||||
pytest-forked==1.0.2
|
||||
pytest-runner==4.4
|
||||
pytest-sugar==0.9.2
|
||||
pytest-xdist==1.27.0
|
||||
python-dateutil==2.8.0
|
||||
python-memcached==1.59
|
||||
python-twitter==3.5
|
||||
pytz==2018.9
|
||||
pyviz-comms==0.7.1
|
||||
pywin32-ctypes==0.2.0
|
||||
pywinpty==0.5.5
|
||||
PyYAML==5.1
|
||||
pyzmq==18.0.1
|
||||
qtconsole==4.4.3
|
||||
ratelim==0.1.6
|
||||
redis==3.2.1
|
||||
requests==2.21.0
|
||||
requests-oauthlib==1.2.0
|
||||
rowingdata==2.2.3
|
||||
rowingphysics==0.5.0
|
||||
rq==0.13.0
|
||||
scipy==1.2.1
|
||||
SecretStorage==3.1.1
|
||||
Send2Trash==1.5.0
|
||||
shell==1.0.1
|
||||
shortuuid==0.5.0
|
||||
simplejson==3.16.0
|
||||
six==1.12.0
|
||||
soupsieve==1.8
|
||||
SQLAlchemy==1.3.1
|
||||
sqlparse==0.3.0
|
||||
stravalib==0.10.2
|
||||
termcolor==1.1.0
|
||||
terminado==0.8.1
|
||||
terminaltables==3.1.0
|
||||
testpath==0.4.2
|
||||
text-unidecode==1.2
|
||||
timezonefinder==4.0.1
|
||||
tornado==6.0.1
|
||||
tqdm==4.31.1
|
||||
traitlets==4.3.2
|
||||
units==0.7
|
||||
uritemplate==3.0.0
|
||||
urllib3==1.24.1
|
||||
VerbalExpressions==0.0.2
|
||||
vine==1.3.0
|
||||
wcwidth==0.1.7
|
||||
webencodings==0.5.1
|
||||
widgetsnbextension==3.4.2
|
||||
winkerberos==0.7.0
|
||||
xmltodict==0.12.0
|
||||
yamjam==0.1.7
|
||||
yamllint==1.15.0
|
||||
@@ -108,9 +108,16 @@ def get_c2_workouts(rower):
|
||||
for item in res.json()['data']:
|
||||
alldata[item['id']] = item
|
||||
|
||||
knownc2ids = uniqify([
|
||||
knownc2ids = [
|
||||
w.uploadedtoc2 for w in Workout.objects.filter(user=rower)
|
||||
])
|
||||
]
|
||||
|
||||
tombstones = [
|
||||
t.uploadedtoc2 for t in TombStone.objects.filter(user=rower)
|
||||
]
|
||||
|
||||
knownc2ids = uniqify(knownc2ids+tombstones)
|
||||
|
||||
newids = [c2id for c2id in c2ids if not c2id in knownc2ids]
|
||||
|
||||
for c2id in newids:
|
||||
|
||||
@@ -1270,6 +1270,7 @@ def new_workout_from_file(r, f2,
|
||||
message = None
|
||||
try:
|
||||
fileformat = get_file_type(f2)
|
||||
print(fileformat,'aa')
|
||||
except IOError:
|
||||
os.remove(f2)
|
||||
message = "Rowsandall could not process this file. The extension is supported but the file seems corrupt. Contact info@rowsandall.com if you think this is incorrect."
|
||||
@@ -1327,7 +1328,13 @@ def new_workout_from_file(r, f2,
|
||||
# worth supporting
|
||||
if fileformat == 'unknown':
|
||||
message = "We couldn't recognize the file type"
|
||||
f4 = f2[:-5]+'a'+f2[-5:]
|
||||
extension = os.path.splitext(f2)[1]
|
||||
filename = os.path.splitext(f2)[0]
|
||||
if extension == '.gz':
|
||||
filename = os.path.splitext(filename)[0]
|
||||
extension2 = os.path.splitext(filename)[1]+extension
|
||||
extension = extension2
|
||||
f4 = filename+'a'+extension
|
||||
copyfile(f2,f4)
|
||||
job = myqueue(queuehigh,
|
||||
handle_sendemail_unrecognized,
|
||||
@@ -1335,6 +1342,9 @@ def new_workout_from_file(r, f2,
|
||||
r.user.email)
|
||||
|
||||
return (0, message, f2)
|
||||
if fileformat == 'att':
|
||||
# email attachment which can safely be ignored
|
||||
return (0, '', f2)
|
||||
|
||||
# handle non-Painsled by converting it to painsled compatible CSV
|
||||
if (fileformat != 'csv'):
|
||||
|
||||
@@ -63,8 +63,8 @@ class LoginForm(forms.Form):
|
||||
class SearchForm(forms.Form):
|
||||
q = forms.CharField(max_length=255,required=False,
|
||||
widget=forms.TextInput(
|
||||
attrs={'placeholder': 'Search'}),
|
||||
label='Search')
|
||||
attrs={'placeholder': 'keyword or leave empty'}),
|
||||
label='Filter by Keyword')
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3227,6 +3227,13 @@ def interactive_flex_chart2(id=0,promember=0,
|
||||
background_fill_color='white',
|
||||
text_color='black',
|
||||
)
|
||||
|
||||
sliderlabel = Label(x=10,y=470,x_units='screen',y_units='screen',
|
||||
text='',
|
||||
background_fill_alpha=0.7,
|
||||
background_fill_color='white',
|
||||
text_color='black',text_font_size='10pt',
|
||||
)
|
||||
|
||||
|
||||
if (xparam != 'time') and (xparam != 'distance') and (xparam != 'cumdist'):
|
||||
@@ -3236,6 +3243,7 @@ def interactive_flex_chart2(id=0,promember=0,
|
||||
|
||||
plot.add_layout(y1means)
|
||||
plot.add_layout(annolabel)
|
||||
plot.add_layout(sliderlabel)
|
||||
|
||||
try:
|
||||
yaxlabel = axlabels[yparam1]
|
||||
@@ -3381,6 +3389,7 @@ def interactive_flex_chart2(id=0,promember=0,
|
||||
y2label=y2label,
|
||||
xlabel=xlabel,
|
||||
annolabel=annolabel,
|
||||
sliderlabel=sliderlabel,
|
||||
y2means=y2means,
|
||||
), code="""
|
||||
var data = source.data
|
||||
@@ -3412,6 +3421,11 @@ def interactive_flex_chart2(id=0,promember=0,
|
||||
var maxdist = maxdist.value
|
||||
var minwork = minwork.value
|
||||
var maxwork = maxwork.value
|
||||
|
||||
sliderlabel.text = 'SPM: '+minspm.toFixed(0)+'-'+maxspm.toFixed(0)
|
||||
sliderlabel.text += ', Dist: '+mindist.toFixed(0)+'-'+maxdist.toFixed(0)
|
||||
sliderlabel.text += ', WpS: '+minwork.toFixed(0)+'-'+maxwork.toFixed(0)
|
||||
|
||||
var xm = 0
|
||||
var ym1 = 0
|
||||
var ym2 = 0
|
||||
|
||||
@@ -137,6 +137,8 @@ def make_new_workout_from_email(rower, datafile, name, cntr=0,testing=False):
|
||||
|
||||
|
||||
# handle non-Painsled
|
||||
if fileformat == 'att':
|
||||
return 0
|
||||
if fileformat != 'csv':
|
||||
filename_mediadir, summary, oarlength, inboard,fileformat = dataprep.handle_nonpainsled(
|
||||
'media/' + datafilename, fileformat, summary)
|
||||
|
||||
@@ -2506,7 +2506,6 @@ class PlannedSessionFormSmall(ModelForm):
|
||||
boattypes = mytypes.boattypes
|
||||
|
||||
# Workout
|
||||
@python_2_unicode_compatible
|
||||
class Workout(models.Model):
|
||||
workouttypes = mytypes.workouttypes
|
||||
workoutsources = mytypes.workoutsources
|
||||
@@ -2611,7 +2610,28 @@ class Workout(models.Model):
|
||||
)
|
||||
|
||||
return stri
|
||||
|
||||
class TombStone(models.Model):
|
||||
user = models.ForeignKey(Rower,on_delete=models.CASCADE)
|
||||
uploadedtoc2 = models.IntegerField(default=0)
|
||||
uploadedtostrava = models.BigIntegerField(default=0)
|
||||
uploadedtosporttracks = models.BigIntegerField(default=0)
|
||||
uploadedtounderarmour = models.BigIntegerField(default=0)
|
||||
uploadedtotp = models.BigIntegerField(default=0)
|
||||
uploadedtorunkeeper = models.BigIntegerField(default=0)
|
||||
|
||||
@receiver(models.signals.pre_delete,sender=Workout)
|
||||
def create_tombstone_on_delete(sender, instance, **kwargs):
|
||||
t = TombStone(
|
||||
user=instance.user,
|
||||
uploadedtoc2 = instance.uploadedtoc2,
|
||||
uploadedtostrava = instance.uploadedtostrava,
|
||||
uploadedtounderarmour = instance.uploadedtounderarmour,
|
||||
uploadedtotp = instance.uploadedtotp,
|
||||
uploadedtorunkeeper = instance.uploadedtorunkeeper,
|
||||
)
|
||||
t.save()
|
||||
|
||||
# delete files belonging to workout instance
|
||||
# related GraphImage objects should be deleted automatically
|
||||
@receiver(models.signals.post_delete,sender=Workout)
|
||||
|
||||
@@ -165,9 +165,15 @@ def get_strava_workouts(rower):
|
||||
w.uploadedtostrava = int(stravaid)
|
||||
w.save()
|
||||
|
||||
knownstravaids = uniqify([
|
||||
knownstravaids = [
|
||||
w.uploadedtostrava for w in Workout.objects.filter(user=rower)
|
||||
])
|
||||
]
|
||||
|
||||
tombstones = [
|
||||
t.uploadedtostrava for t in TombStone.objects.filter(user=rower)
|
||||
]
|
||||
|
||||
knownstravaids = uniqify(knownstravaids+tombstones)
|
||||
|
||||
newids = [stravaid for stravaid in stravaids if not stravaid in knownstravaids]
|
||||
|
||||
|
||||
@@ -1026,7 +1026,7 @@ def handle_sendemail_breakthrough(workoutid, useremail,
|
||||
d = {
|
||||
'first_name':userfirstname,
|
||||
'siteurl':siteurl,
|
||||
'workoutid':workoutid,
|
||||
'workoutid':encoder.encode_hex(workoutid),
|
||||
'btvalues':tablevalues,
|
||||
}
|
||||
|
||||
@@ -1071,7 +1071,7 @@ def handle_sendemail_hard(workoutid, useremail,
|
||||
d = {
|
||||
'first_name':userfirstname,
|
||||
'siteurl':siteurl,
|
||||
'workoutid':workoutid,
|
||||
'workoutid':encoder.encode_hex(workoutid),
|
||||
'btvalues':tablevalues,
|
||||
}
|
||||
|
||||
@@ -1661,6 +1661,8 @@ def handle_makeplot(f1, f2, t, hrdata, plotnr, imagename,
|
||||
haspower = row.df[' Power (watts)'].mean() > 50
|
||||
except TypeError:
|
||||
haspower = True
|
||||
except KeyError:
|
||||
haspower = False
|
||||
|
||||
nr_rows = len(row.df)
|
||||
if (plotnr in [1, 2, 4, 5, 8, 11, 9, 12]) and (nr_rows > 1200):
|
||||
|
||||
@@ -72,16 +72,13 @@
|
||||
</script>
|
||||
|
||||
{% if rower.user %}
|
||||
<h1>{{ rower.user.first_name }} Power Estimates</h1>
|
||||
<h1>Power Progress for {{ rower.user.first_name }} </h1>
|
||||
{% else %}
|
||||
<h1>{{ user.first_name }} Power Estimates</h1>
|
||||
<h1>Power Progress for {{ user.first_name }} </h1>
|
||||
{% endif %}
|
||||
|
||||
|
||||
<ul class="main-content">
|
||||
<li class="grid_4">
|
||||
{{ the_div|safe }}
|
||||
</li>
|
||||
<li class="grid_2">
|
||||
<form enctype="multipart/form-data" action="/rowers/fitness-progress/user/{{ rower.user.id }}/" method="post">
|
||||
<table>
|
||||
@@ -92,6 +89,9 @@
|
||||
</form>
|
||||
|
||||
</li>
|
||||
<li class="grid_4">
|
||||
{{ the_div|safe }}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
<ul class="main-content">
|
||||
<li class="grid_4">
|
||||
<div id="theplot" class="flexplot" style="min-width:300px;">
|
||||
<div id="theplot" class="flexplot">
|
||||
{{ the_div|safe }}
|
||||
</div>
|
||||
</li>
|
||||
@@ -51,8 +51,8 @@
|
||||
{{ optionsform.as_table }}
|
||||
</table>
|
||||
<p>
|
||||
<input name="chartform" class="button green" type="submit"
|
||||
value="Submit">
|
||||
<input name="chartform" type="submit"
|
||||
value="Update Chart">
|
||||
</p>
|
||||
</form>
|
||||
</li>
|
||||
|
||||
@@ -69,27 +69,20 @@
|
||||
{{ the_div |safe }}
|
||||
</li>
|
||||
<li class="grid_2">
|
||||
<p>
|
||||
<p>Filter on date
|
||||
<form enctype="multipart/form-data" method="post">
|
||||
<table>
|
||||
{{ dateform.as_table }}
|
||||
</table>
|
||||
{% csrf_token %}
|
||||
<input name='daterange' type="submit" value="Submit">
|
||||
</form>
|
||||
</p>
|
||||
{% if team %}
|
||||
<p>and keyword</p>
|
||||
<p>
|
||||
<form id="searchform" action="/rowers/list-workouts/team/{{ team.id }}/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}/"
|
||||
method="get" accept-charset="utf-8">
|
||||
{% else %}
|
||||
<form id="searchform" action="/rowers/list-workouts/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}/"
|
||||
method="get" accept-charset="utf-8">
|
||||
{% endif %}
|
||||
{{ searchform }}
|
||||
<input type="submit" value="GO">
|
||||
</input>
|
||||
</form>
|
||||
{{ searchform }}
|
||||
</p>
|
||||
<p>
|
||||
<input name='daterange' type="submit" value="Select workouts">
|
||||
</form>
|
||||
</p>
|
||||
<p>
|
||||
{% if rankingonly and not team %}
|
||||
|
||||
@@ -283,7 +283,7 @@ class URLTests(TestCase):
|
||||
for u in urls:
|
||||
if u not in tested and 'rowers' in u and 'http' not in u and 'authorize' not in u and 'import' not in u and 'logout' not in u:
|
||||
response2 = self.c.get(u)
|
||||
if response2.status_code not in [200,302]:
|
||||
if response2.status_code not in [200,302,301]:
|
||||
print(len(tested))
|
||||
print(response.templates[0].name)
|
||||
print(url)
|
||||
@@ -291,7 +291,7 @@ class URLTests(TestCase):
|
||||
print(response2.status_code)
|
||||
tested.append(u)
|
||||
self.assertIn(response2.status_code,
|
||||
[200,302])
|
||||
[200,302,301])
|
||||
else:
|
||||
tested.append(u)
|
||||
|
||||
|
||||
3
rowers/tests/testdata/emails/ATT00001.txt
vendored
Normal file
3
rowers/tests/testdata/emails/ATT00001.txt
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
|
||||
|
||||
|
||||
1589
rowers/tests/testdata/emails/RitmoTime_20190321_0805_Full-Workout.csv
vendored
Normal file
1589
rowers/tests/testdata/emails/RitmoTime_20190321_0805_Full-Workout.csv
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -611,11 +611,24 @@ def fitnessmetric_view(request,id=0,mode='rower',
|
||||
enddate=enddate,
|
||||
)
|
||||
|
||||
breadcrumbs = [
|
||||
{
|
||||
'url':'/rowers/analysis',
|
||||
'name':'Analysis'
|
||||
},
|
||||
{
|
||||
'url':reverse('fitnessmetric_view'),
|
||||
'name': 'Power Progress'
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
return render(request,'fitnessmetric.html',
|
||||
{
|
||||
'rower':therower,
|
||||
'active':'nav-analysis',
|
||||
'chartscript':script,
|
||||
'breadcrumbs':breadcrumbs,
|
||||
'the_div':thediv,
|
||||
'mode':mode,
|
||||
'form':form,
|
||||
|
||||
@@ -522,9 +522,11 @@ def rower_register_view(request):
|
||||
title='New User Sample Data',
|
||||
notes='This is an example workout to get you started')
|
||||
newworkoutid = response[0]
|
||||
w = Workout.objects.get(id=newworkoutid)
|
||||
w.startdatetime = timezone.now()
|
||||
w.save()
|
||||
if newworkoutid:
|
||||
w = Workout.objects.get(id=newworkoutid)
|
||||
w.startdatetime = timezone.now()
|
||||
w.date = timezone.now().date()
|
||||
w.save()
|
||||
|
||||
# Create and send email
|
||||
fullemail = first_name + " " + last_name + " " + "<" + email + ">"
|
||||
|
||||
@@ -1178,12 +1178,15 @@ def workouts_view(request,message='',successmessage='',
|
||||
startdate = datetime.datetime.combine(startdate,datetime.time())
|
||||
enddate = datetime.datetime.combine(enddate,datetime.time(23,59,59))
|
||||
|
||||
|
||||
query = None
|
||||
if request.method == 'POST':
|
||||
dateform = DateRangeForm(request.POST)
|
||||
searchform = SearchForm(request.POST)
|
||||
if dateform.is_valid():
|
||||
startdate = dateform.cleaned_data['startdate']
|
||||
enddate = dateform.cleaned_data['enddate']
|
||||
if searchform.is_valid():
|
||||
query = searchform.cleaned_data['q']
|
||||
else:
|
||||
dateform = DateRangeForm(initial={
|
||||
'startdate':startdate,
|
||||
@@ -1293,7 +1296,6 @@ def workouts_view(request,message='',successmessage='',
|
||||
for w in workoutsnohr:
|
||||
res = dataprep.workout_trimp(w)
|
||||
|
||||
query = request.GET.get('q')
|
||||
if query:
|
||||
query_list = query.split()
|
||||
workouts = workouts.filter(
|
||||
|
||||
@@ -70,7 +70,7 @@ body {
|
||||
}
|
||||
|
||||
.yellow {
|
||||
color: #cccc00;
|
||||
color: #1c75bc;
|
||||
font-size: 1.2em;
|
||||
height: auto;
|
||||
padding: 0px;
|
||||
@@ -1005,6 +1005,7 @@ th.rotate > div > span {
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
|
||||
a.wh:link {
|
||||
color: #e9e9e9;
|
||||
}
|
||||
|
||||
@@ -564,28 +564,28 @@
|
||||
|
||||
|
||||
|
||||
@media (min-height: 600px) {
|
||||
@media only screen and (min-height: 600px) {
|
||||
.maxheight {
|
||||
max-height: 450px;
|
||||
overflow: scroll;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-height: 600px) {
|
||||
@media only screen and (min-height: 600px) {
|
||||
.maxheight {
|
||||
max-height: 450px;
|
||||
overflow: scroll;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-height: 800px) {
|
||||
@media only screen and (min-height: 800px) {
|
||||
.maxheight {
|
||||
max-height: 600px;
|
||||
overflow: scroll;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-height: 1000px) {
|
||||
@media only screen and (min-height: 1000px) {
|
||||
.maxheight {
|
||||
max-height: 800px;
|
||||
overflow: scroll;
|
||||
@@ -593,7 +593,7 @@
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 600px) {
|
||||
@media only screen and (max-width: 600px) {
|
||||
nav a {
|
||||
font-size: 0px;
|
||||
}
|
||||
@@ -601,9 +601,22 @@
|
||||
nav a i {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
#theplot .bk-grid-column {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#theplot .bk-plot-layout {
|
||||
position: auto;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 450px) {
|
||||
|
||||
|
||||
@media only screen and (min-width: 450px) {
|
||||
.wrapper {
|
||||
grid-template-columns: 1fr 3fr;
|
||||
grid-template-areas:
|
||||
@@ -648,7 +661,7 @@
|
||||
}
|
||||
|
||||
|
||||
@media (min-width: 768px) {
|
||||
@media only screen and (min-width: 768px) {
|
||||
.wrapper {
|
||||
grid-template-columns: 1fr 4fr 1fr;
|
||||
grid-template-areas:
|
||||
@@ -727,7 +740,7 @@
|
||||
page-break-after: avoid;
|
||||
}
|
||||
|
||||
ul, img {
|
||||
ul, img, table {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user